Corona游戏开发with lua(项目2-游戏制作)

官方网址:https://docs.coronalabs.com/guide/programming/02/index.html

Corona 知识:每建立一个空白corona项目,除main.lua以外,都会包含build.settings和config.lua。

1、build.settings:该文件为真实设备(手机、平板)提供了有关应用程序所需的详细信息。包括应用支持的方向、图标文件的名称、要包含的插件、设备所需的特殊信息等。

例如:此游戏需锁定屏幕方向为竖向,即使用户旋转屏幕,游戏仍然为竖向。

用文本编辑器打开build.settings文件。(我用VS打不开,改用记事本打开的)

找到其中这一段代码:

     orientation =
     {
         -- Supported values for orientation:
         -- portrait, portraitUpsideDown, landscapeLeft, landscapeRight
 
         default = "portrait" ,
         supported = { "portrait" , },
     },

其中:default="portrait" 表示用户第一次加载游戏时默认以竖屏开始。

          supported={"portrait",}, 表示游戏唯一支持的方向是竖向,即使用户转屏幕也不会改变。

【花括号表示lua语言中的table,可以包含多个元素,比如至多4个方向,但由于此游戏只需要竖向,所以花括号里一个足够。】

2、config.lua:包含所有corona的应用程序的配置设置。这里可以指定应用程序运行的分辨率,内容比例模式,如何处理高分辨率的设备等。

     content =
     {
         width = 768,
         height = 1024,
         scale = "letterbox" ,

其中,scale有三种方案:letterbox【不拉伸,留黑条】、zoomEven【不拉伸,裁剪占满屏幕】、zoomStretch【拉伸占满屏幕】。

此游戏适合zoomEven。

游戏设计:

游戏标题 Star Explorer - 太空射击游戏。
描述 在小行星场中操纵你的星舰,随着你的进步摧毁小行星。
控制 点击船上开火; 拖动船左右移动。
声音 当船与小行星碰撞时拍摄声音和爆炸声。

【添加物理】

local physics=require("physics")

physics.start( )

physics.setGravity(0,0)【设置重力值,默认为地球引力,这里水平x、垂直y都设为0】

math.randomseed(os.time( ) )【随机种子】

【图像表格】

local sheetOptions=

{

     frame=

     {

         {x=0,y=0,width=102,height=85},--第1帧

         {x=0,y=85,width=90,height=83},--第2帧

         {x=0,y=168,width=100,height=97},--第3帧

         {x=0,y=265,width=98,height=79},--第4帧

         {x=98,y=265,width=14,height=40},--第5帧

     },

}【1,2,3,4,5分别对应5张图,均从一张图上切割而来】

【初始化】

local objectSheet =graphics.newImageSheet("gameObjects.png",sheetOptions)

local lives=3

local score=0

local dead=false

local asteroidsTable={ }【行星表】

local ship

local gameLoopTimer

local livesText

local scoreText

【显示】

local backGroup=dispaly.newGroup( )

local mainGroup=display.newGroup( )

local uiGroup=display.newGroup( )

local background=display.newImageRect(backGroup,"backgroup.png",800,1400)【backGroup表示将加载的图片插入该组】

background.x=display.contentCenterX

background.y=display.contentCenterY

ship=display.newImageRect(mainGroup,objectSheet,4,98,79)【ship为objectSheet图表中的第4张】

ship.x=display.contentCenterX

ship.y=display.contentHeight-100

physics.addBody(ship, {radius=30, isSensor=true} )【isSensor=true表示添加传感器,检测碰撞但不反弹】

ship.myName="ship"

【生命和分数】

livesText=newText( uiGroup, "lives:"..lives, 200, 80, native.systemFont, 36)【这里的..用来串联两个字符串】

scoreText=newText( uiGroup, "score:"...score, 400, 80, native.systemFont, 36)

display.setStatusBar(display.HiddenStatusBar) 【隐藏状态栏】

local function updateText( )【更新文本函数】

livesTxet.text="lives:"..lives

scoreText.text="score:"..score

end

【行星函数】

local function createAsteriod()

local newAsteriod=display.newImageRect(mainGroup,objectSheet,1,102,85)

table.insert(asteroidTable,newAsteriod)【新建的行星图片加入行星表中】

physics.addBody(newAsteriod,"dynamic",{radius=40,bounce=0.8})

newAsteriod.myName="asteriod"

local whereFrom=math.random(3)

     if(whereFrom==1) then

     newAsteriod.x=-60

     newAsteriod.y=math.random(500)

     newAsteriod:setLinearVelocity(math.random(40,120),math.random(20,60))

     elaeif(whereFrom==2) then

     newAsteriod.x=math.random(display.contentWidth)

     newAsteriod.y=-60

     newAsteriod:setLinearVelocity(math.random(-40,40),math.random(40,120))

     elseif(whereFrom==3) then

     newAsteriod.x=display.contentWidth+60

     newAsteriod.y=math.random(500)

     newAsteriod:setLinearVelocity(math.random(-120,-40),math.random(20,60))

     end

newAsteriod:applyTorque(math.random(-6,6))【施加扭转力】

end

【激光函数】

local function fireLaser()

local newLaser=display.newImageRect(mainGroup,objectSheet,5,14,40)

physics.addBody(newLaser,"dynamic", {isSenser=true})

newLaser.isBullet=true【使激光接受连续碰撞检测而不是世界时间步骤的周期性碰撞检测,确保不会“穿过”任何行星】

newLaser.myName="laser"

newLaser.x=ship.x

newLaser.y=ship.y

newLaser:toBack()【将对象发送到自己显示组的最后面】

transition.to(newLaser,{y=-60,time=500,onComplete=function() display.remove(newLaser) end})【过渡,第二个参数包含一个表,使对象到达y=-60的目标,时间为500毫秒,完成后调用onComplete函数(这里是个匿名函数),进行清理。】

end

ship:addEventListener("tap",fireLaser)

【移动船】

local function dragShip(event)

local ship=event.target

local phase=event.phase

if("begin"==phase) then

display.currentStage:setFocus(ship)【把触摸焦点设置在ship上】

ship.touchOffsetX=event.x-ship.x【存储最初的偏移量】

elseif("move"==phase) then

ship.x=event.x-ship.touchOffsetX【移动ship】

elseif("ended"==phase or "cancelled"==phase) then

display.currentStage:setFocus(nil)

end

return true【告诉corona触摸事件应该“停止”在这个对象上,而不是传播到底层对象】

end

ship:addEventListener("touch",dragShip)

【游戏循环】---创造新的小行星并清理“死”小行星

local function gameLoop()

createAsteriod()

    for i=#asteriodsTable,1,-1 do【表名前面加#可以得到表中元素的数量】

local thisAsteriod=asteriodsTable[i]

        if(thisasteriod.x<-100 or thisasteriod.x>display.contentWidth+100 or

 thisasteriod.y<-100 or thisasteriod.y>display.contentHeight+100) 

then

display.remove(thisAsteriod)【从视觉上删除屏幕上小行星,但不释放内存,因为表中存储了对小行星的附加引用,所以需要下一步】

table.remove(asteriodsTable,i)【删除表中元素】

        end

   end

end

gameLoopTimer=timer.performWithDelay(500,gameLoop,0)【定时器,延迟500毫秒执行一次,最后是迭代次数,注意0或-1会导致计时器无限重复】

【碰撞处理】---恢复船只

local function restoreShip()

ship.isBodyActive=false【停止ship的物理模拟,停止交互】

ship.x=display.contentCenterX

ship.y=display.contentHeight-100

transition.to(ship, {alpha=1,time=4000,onComplete=function() ship.isBody=true died=false end})

end

【碰撞处理】---碰撞功能

local function onCollision(event)

if(event.phase=="began") then 

local obj1=event.object1

local obj2=event.object2

     if( (obj1.myName=="laser" and obj2.myName=="asteriod") or  【激光和小行星碰撞】

     (obj2.myName=="laser" and obj1.myName=="asteriod"))

     then

     display.remove(obj1)

     display.remove(obj2)

     for  i=#asteriodsTable,1,-1 do

     if(asteriodsTable[i]==obj1 or asteriodsTable[i]==obj2) then

     table.remove(asteriodsTable,i)

     break

     end

     end

     score=score+100

     scoreText.text="score:"..score

     elseif( (obj1.myName=="ship" and obj2.myName=="asteriod") or  【船和小行星碰撞】

     (obj2.myName=="ship" and obj1.myName=="asteriod"))

     then

     if(died=false) then 

     died=true 

     lives=lives-1

     livesText.text="lives:"..lives

     if(lives==0) then

     diaplay.remove(ship)

     else

     ship.alpha=0

     timer.performWithDelay(1000,restoreShip)

     end

     end

     end

end

end

Runtime:addEventListener("collision",onCollision)

//知识总结

命令/物业 描述
physics.setGravity() 以m /s²为单位设置全球重力矢量xy分量。
math.randomseed() 设置伪随机数生成器的“种子” 
graphics.newImageSheet() 创建一个ImageSheet对象,用于从单个较大的图像文件中加载多个图像/帧。
display.newGroup() 创建用于组织/分层显示对象的显示组。
display.contentHeight 内容区域高度的快捷方式。
display.setStatusBar() 隐藏或更改大多数设备上状态栏的外观
命令/物业 描述
table.insert() 将给定值插入表中
table.remove() 指定索引处的删除项
的Math.random() 从具有均匀分布的序列返回伪随机数。
对象:setLinearVelocity() 设置主体线速度xy分量。
对象:applyTorque() 对身体施加旋转力。
object.isBullet 是否应将身体视为“子弹”的布尔值。
对象:toBack后() 将目标对象移动到其父组的可视后退。
transition.to() 使用可选的缓动算法为显示对象设置动画(过渡)
display.remove() 如果没有,则删除对象或组nil
对象:的setFocus() 将特定显示对象设置为所有未来命中事件"touch""tap")的目标
timer.performWithDelay() 延迟后调用指定的函数。
object.isBodyActive 设置或获取物理实体的当前活动状态。

触摸事件

与点击事件不同的触摸事件根据用户触摸的状态有四个不同的阶段

  • "began" - 表示已在对象上开始触摸(屏幕上的初始触摸)。
  • "moved" - 表示触摸位置已在对象上移动。
  • "ended" - 表示触摸已在对象上结束(触摸从屏幕上抬起)。
  • "cancelled"- 表示系统取消了对触摸的跟踪(不要混淆  "ended")。



    

你可能感兴趣的:(Corona游戏开发with lua(项目2-游戏制作))