博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
love2d教程5--摄相机1视角跟随玩家
阅读量:5285 次
发布时间:2019-06-14

本文共 4769 字,大约阅读时间需要 15 分钟。

这篇教程来自wiki的Tutorial:Cameras的阅读笔记,有些没看懂,先写一部分.

Part 1: The Basics
Part 2: Parallax Scrolling
Part 3: Movement Bounds
作者为BlackBulletIV,感想他的好教程,大家可以到他的网站看看
有很多非常好的love2d和lua文章,他的github ,也有很多好东西
love2d的坐标系统变换有三个函数
love.graphics.translate( dx, dy ) --平移变换,变换后坐标为x+dx,y+dy
love.graphics.rotate( angle ) --旋转变换,逆时针旋转angle弧度
love.graphics.scale( sx, sy ) --缩放变换,参数大于1会放大,小于1则缩小,0没意义.

整个坐标系都会变换,当为负数时会左右/上下颠倒.

首先介绍坐标系统状态的保存与恢复.
push 首先保存绘图前的状态,pop用push保存的状态.
下面是例子,你可以试试注释掉部分函数.

function love.draw()    --如果把push和pup注释,你会看到它们挤在一起   love.graphics.push()   love.graphics.scale(2, 2)    love.graphics.print("scaled text", 50, 50)   love.graphics.pop()   love.graphics.print("normal text", 50, 50)end

摄相机的原理就是让视角和玩家相对静止,

地图向相反方向移动,所以我们把地图的
初始坐标减去某个坐标差就得到了地图
的正确位置.
现在我们创建一个摄相机类camera

camera = {}--平移变换的x,y偏移camera._x = 0camera._y = 0--缩放变换的x,y系数camera.scaleX = 1camera.scaleY = 1--旋转变换的角度camera.rotation = 0

 

 

由于坐标变换时每次都要

love.graphics.push()
--变换函数的代码
love.graphics.pup()

可以写个函数把它们统一,如下
--保存坐标系统

function camera:set()  love.graphics.push()  --self前的"-"表示负号  love.graphics.rotate(-self.rotation)  love.graphics.scale(1 / self.scaleX, 1 / self.scaleY)  love.graphics.translate(-self._x, -self._y)end--恢复保存的坐标系统function camera:unset()  love.graphics.pop()end

为什么都是负的呢? 如果物体不和摄相机一同移动,让

其坐标落在摄相机后面(-rotation,-x,-y);远处的物体运动慢,近
处的运动快,远处物体小,近处物体大(-rotation).这和生活中坐
车是一样的道理.

这样当需要变换坐标时,先set,变换完后unset恢复,就方便多了.

下面我们来实现视角跟随玩家

这里只涉及平移,当玩家向左移动时,坐标系统向右平移.

如果我们在平移后画地图和玩家,由于整体都向右移动了,如果让坐标系统平移的距离和玩家向左

运动的距离相等,那么玩家的实际运动距离就为0了.

即让camera._x=player.X(本次)-player.X(上次)

显然玩家的坐标在不断的变化,我们可以直接在update回调函数里加上一句:

camera:setOffset(player.X-player.X(初始), player.Y-player.Y(初始))

因为玩家已经不动了,所以直接让player.X(上次)=player.X(初始),

在代码里你会看到(400,300)那是我把player的坐标设为了(400,300)了.

camera:setOffse()的代码如下:

--设置摄相机的x偏移 function camera:setX(value)   self._x = value end --设置摄相机的y偏移 function camera:setY(value)     self._y = value end function camera:setOffset(x, y)   if x then self:setX(x) end   if y then self:setY(y) end end

完整的代码如下:我添加了玩家的放大,缩小,旋转事件,可以用鼠标操作.

代码下载:

 

main.lua

tilemap=require('tilemap')require('maptool')require('camera')--地图在屏幕上显示的左上角x,y坐标tilemap._X,tilemap._Y=-80,-180tilemap._rot=0tilemap._sx=1tilemap._sy=1quadtable={}player={}player.X=400player.Y=300player.rot=0player.sx=1player.sy=1speed=300function love.load()    image=love.graphics.newImage("assets/" .. tilemap["tilesets"][1].name ..tilemap["properties"]["format"])    makeQuad(tilemap)    player.img=love.graphics.newImage("assets/player.png")    mainfont = love.graphics.newFont( 20 )endfunction love.draw()    camera:set()    drawMap(tilemap,image)    love.graphics.draw(player.img,player.X,player.Y,    player.rot,player.sx,player.sy,player.    --设置图片的中心    img:getWidth() / 2,player.img:getHeight() / 2)    camera:unset()    love.graphics.setFont(mainfont);    love.graphics.print("player.X=" .. player.X .. "  player.Y=" .. player.Y,20,20)endfunction love.update(dt)    --平移    if(love.keyboard.isDown("up")) then    player.Y=player.Y-speed*dt    end    if(love.keyboard.isDown("down")) then    player.Y=player.Y+speed*dt    end    if(love.keyboard.isDown("left")) then    player.X=player.X-speed*dt    end    if(love.keyboard.isDown("right")) then    player.X=player.X+speed*dt    end    --旋转    if(love.keyboard.isDown("j")) then    player.rot=player.rot-0.5    end    if(love.keyboard.isDown("l")) then    player.rot=player.rot+0.5    end    --缩放    if (love.keyboard.isDown("i")) then    player.sx=player.sx+0.1    player.sy=player.sy+0.1    end    if (love.keyboard.isDown("k")) then    player.sx=player.sx-0.1    player.sy=player.sy-0.1    end    --设置摄相机的偏移    camera:setOffset(player.X-400, player.Y-300)endfunction love.keypressed(key)end--鼠标事件function love.mousepressed(x,y,button)    if button=="wd" then        player.sx=player.sx-0.1        player.sy=player.sy-0.1    end    if button=="wu" then        player.sx=player.sx+0.1        player.sy=player.sy+0.1    endend

camera.lua

camera = {}--平移变换的x,y偏移camera._x = 0camera._y = 0--缩放变换的x,y系数camera.scaleX = 1camera.scaleY = 1--旋转变换的角度camera.rotation = 0--保存变换前的坐标系统,并进行平移,缩放,旋转变换function camera:set()  love.graphics.push()  love.graphics.rotate(-self.rotation)  love.graphics.scale(1 / self.scaleX, 1 / self.scaleY)  love.graphics.translate(-self._x, -self._y)end--恢复保存的坐标系统function camera:unset()  love.graphics.pop()endfunction camera:rotate(dr)  self.rotation = self.rotation + drendfunction camera:scale(sx, sy)  sx = sx or 1  self.scaleX = self.scaleX * sx  self.scaleY = self.scaleY * (sy or sx)end--设置摄相机的x偏移function camera:setX(value)  self._x = valueend--设置摄相机的y偏移function camera:setY(value)    self._y = valueendfunction camera:setOffset(x, y)  if x then self:setX(x) end  if y then self:setY(y) endend

 

转载于:https://www.cnblogs.com/xdao/archive/2012/12/16/love2d-tutor05.html

你可能感兴趣的文章
安装NVIDIA驱动时禁用自带nouveau驱动
查看>>
HDU-1255 覆盖的面积 (扫描线)
查看>>
Java 中 静态方法与非静态方法的区别
查看>>
Jenkins+ProGet+Windows Batch搭建全自动的内部包(NuGet)打包和推送及管理平台
查看>>
线程池的概念
查看>>
Java 序列化
查看>>
Java 时间处理实例
查看>>
Java 多线程编程
查看>>
Java 数组实例
查看>>
mysql启动过程
查看>>
利用AMPScript获取Uber用户数据的访问权限
查看>>
Mysql 数据库操作
查看>>
转:linux终端常用快捷键
查看>>
UVa 11059 最大乘积
查看>>
数组分割问题求两个子数组的和差值的小
查看>>
161017、SQL必备知识点
查看>>
kill新号专题
查看>>
MVC学习系列——Model验证扩展
查看>>
Suite3.4.7和Keil u3自带fx2.h、fx2regs.h文件的异同
查看>>
打飞机游戏【来源于Crossin的编程教室 http://chuansong.me/account/crossincode 】
查看>>