cocos2dx 3.2之Lua打飞机项目
1??????????創建lua打飛機項目
cocos new T32Lua -dE:\Installed\cocos2d-x-3.2\cocos2d-x-3.2\projects -l lua
2 ?項目代碼
| Common.lua |
| --用于打印日志信息 function cclog(...) ??? print(string.format(...)) end ? function createBackMenu(node, callback) ??? -- 獲得窗口的大小 ??? local winSize = cc.Director:getInstance():getWinSize() ? ??? -- 創建菜單 ??? local menu = cc.Menu:create() ??? -- node中加入菜單 ??? node:addChild(menu) ? ??? --local function startGame() ??? --? cc.Director:getInstance():replaceScene(SceneMenu()) ??? --end ? ??? -- 加菜單項 ??? local menuItem = cc.MenuItemImage:create("btn_back_normal.png", "btn_back_press.png") ??? -- 菜單中添加菜單項 ??? menu:addChild(menuItem) ??? -- 注冊處理函數 ??? menuItem:registerScriptTapHandler(callback) -- 注冊處理函數 ? ??? -- menu的錨點默認是在屏幕正中間的,將它設置在屏幕右下角 ??? menuItem:setAnchorPoint(cc.p(1, 0)) ??? -- 重新設置菜單項的位置 ??? menuItem:setPosition(winSize.width/2, -winSize.height/2); ??? -- 設置縮放,在2.3中x方向和y方向上的縮放比例必須相同,但是在3.2中沒有限制 ??? menuItem:setScale(2) end ? -- 設置觸摸事件 function regTouch(node, onTouchBegan, onTouchEnded, onTouchMoved) ??? local evListen = cc.EventListenerTouchOneByOne:create() ??? evListen:registerScriptHandler(onTouchBegan, cc.Handler.EVENT_TOUCH_BEGAN) ? ??? -- 如果onTouchEnded不為空 ??? if onTouchEnded ~= nil then ??????? evListen:registerScriptHandler(onTouchEnded, cc.Handler.EVENT_TOUCH_ENDED) ??? end ? ??? -- 如果onTouchMoved不為空 ??? if onTouchMoved ~= nil then ??????? evListen:registerScriptHandler(onTouchMoved, cc.Handler.EVENT_TOUCH_MOVED) ??? end ? ??? -- 如果 ??? local evDisp = node:getEventDispatcher() ??? evDisp:addEventListenerWithSceneGraphPriority(evListen, node) end |
| LayerScrollBackground.lua?? 滾動的背景 |
| require "Common" ? function LayerScrollBackground() ??? local layer = cc.Layer:create() ??? -- 獲得屏幕的大小 ??? local winSize = cc.Director:getInstance():getWinSize() ? ??? -- 加背景 ??? local bg = cc.Sprite:create("background.png") ??? -- 層中添加作為背景的精靈 ??? layer:addChild(bg) ??? -- 設置精靈的錨點 ??? bg:setAnchorPoint(0, 0) ? ??? -- 需要兩個動作,一個動作向下移動,一個動作設置位置 ??? local action1 = cc.MoveBy:create(10, {x=0, y=-winSize.height}) ??? local action2 = cc.Place:create({x=0, y=0}) ??? local action = cc.Sequence:create(action1, action2) ??? -- 執行動作 ??? bg:runAction(cc.RepeatForever:create(action)) ? ??? return layer end |
| SceneMenu.lua 菜單 |
| require "Common" require "LayerScrollBackground" require "SceneGame" ? function SceneMenu() ??? local scene = cc.Scene:create() ? ??? local winSize = cc.Director:getInstance():getWinSize() ? ??? -- 滾動的背景 ??? local bgLayer = LayerScrollBackground() ??? scene:addChild(bgLayer) ? ??? -- ScrollView ??? cc.SpriteFrameCache:getInstance():addSpriteFrames("chooselevel.plist") ? ??? local node = cc.Node:create() ??? for i = 1, 5 do ??????? local spriteName = "ChooseLevel" .. i ..? ".png" ??????? local spriteFrame = cc.SpriteFrameCache:getInstance():getSpriteFrame(spriteName) ??????? local sprite = cc.Sprite:createWithSpriteFrame(spriteFrame) ??????? node:addChild(sprite) ??????? sprite:setPosition(winSize.width/2 + winSize.width*(i-1), winSize.height/2) ??????? sprite:setTag(1000+i) ??? end ? ??? local scrollView = cc.ScrollView:create(winSize, node) ??? scene:addChild(scrollView) ? ??? scrollView:setContentSize(winSize.width*5, winSize.height) ??? scrollView:setDirection(0) ? ??? -- 增加Touch處理 ??? local function onTouchBegan(touch, event) ??????? return true ??? end ??? local function onTouchEnded(touch, event) ??????? local sLoc = touch:getStartLocation() ??????? local dLoc = touch:getLocation() ??????? local d = {x=sLoc.x - dLoc.x, y=sLoc.y-dLoc.y} ??????? local pt = node:convertToNodeSpace(sLoc) ? ??????? if d.x*d.x+d.y*d.y < 25 then ??????????? for i=1, 5 do ??????????????? local sprite = node:getChildByTag(1000+i) ??????????????? local rc = sprite:getBoundingBox() ??????????????? if cc.rectContainsPoint(rc, pt) then ??????????????????? ?cc.Director:getInstance():replaceScene(SceneGame(i)) ??????????????????? ?cclog("start new game " .. i) ??????????????? end ??????????? end ??????? end ??? end ? ??? regTouch(scene, onTouchBegan, onTouchEnded) ? ??? local function Back() ??????? cc.Director:getInstance():replaceScene(SceneStart()) ??? end ??? createBackMenu(scene, Back) ??? ??? return scene end |
| SceneStart.lua |
| require "SceneMenu" require "Common" ? function SceneStart() ??? local scene = cc.Scene:create() ? ??? local winSize = cc.Director:getInstance():getWinSize() ? ??? cclog(winSize.width .. winSize.height) ? ??? -- 加背景圖片 ??? local bg = cc.Sprite:create("background.png") ??? scene:addChild(bg) ??? bg:setPosition(winSize.width/2, winSize.height/2) ? ??? -- 加菜單按鈕 ??? local menu = cc.Menu:create() ??? scene:addChild(menu) ? ??? local function startGame() ??????? cc.Director:getInstance():replaceScene(SceneMenu()) ??? end ? ??? -- 加菜單項 ??? local menuItemStart = cc.MenuItemImage:create("btn1_normal.png", "btn1_push.png") ??? menu:addChild(menuItemStart) ??? menuItemStart:registerScriptTapHandler(startGame) -- 注冊處理函數 ? ??? return scene end |
| SceneGame.lua |
| require "Common" require "LayerScrollBackground" ? function SceneGame(idx) ??? --創建 ??? local scene = cc.Scene:create() ??? local winSize = cc.Director:getInstance():getWinSize() ? ??? -- 滾動的背景 ??? local bgLayer = LayerScrollBackground() ??? -- 場景中加上層 ??? scene:addChild(bgLayer) ? ??? -- 數據結構,子彈的數組和敵機的數組 ??? local bullets = {} ??? -- 添加敵機 ??? local enemys = {} ? ??? -- 創建英雄戰機 ??? local plane = cc.Sprite:create("Player" .. idx .. ".png") ??? -- 場景中添加飛機 ??? scene:addChild(plane) ??? -- 設置飛機的位置 ??? plane:setPosition(winSize.width/2, plane:getBoundingBox().height) ??? -- 設置plane的ZOrder ??? plane:setLocalZOrder(100) ? ??? ----- 加載戰斗機的屬性 ??? local vm =? cc.FileUtils:getInstance():getValueMapFromFile("planeinfo.xml"); ??? plane.damage = tonumber(vm["planedamageamount" .. idx]) ??? plane.hp = tonumber(vm["plane" .. idx .. "_hp"]) ??? plane.cd = tonumber(vm["planeshootspeedrate" .. idx]) ??? plane.curCD = 0; ? ??? cclog(plane.damage .. " " .. plane.hp .. " " .. plane.cd) ? ??? -- 顯示分數和血的Label ??? local labelScore = nil ??? local labelHP = nil ??? local function createLabels() ??? ??? -- 設置label ??????? labelHP = cc.Label:createWithSystemFont("" .. plane.hp, "Arial", 50) ??????? -- 設置Label的錨點 ??????? labelHP:setAnchorPoint(cc.p(1, 1)) ??????? -- 設置錨點的位置 ??????? labelHP:setPosition(winSize.width, winSize.height) ??????? scene:addChild(labelHP) ??????? labelHP:setLocalZOrder(1010) ? ??????? labelScore = cc.Label:createWithSystemFont("0", "Arial", 50) ??????? labelScore:setAnchorPoint(cc.p(0, 1)) ??????? labelScore:setPosition(0, winSize.height) ??????? scene:addChild(labelScore) ??????? labelScore:setLocalZOrder(1010) ??? end ??? createLabels() ? ??? -- 移動飛機 ? ??? -- 增加Touch處理 ??? local function onTouchBegan(touch, event) ??????? return true ??? end ??? local function onTouchMoved(touch, event) ??????? local x, y = plane:getPosition() ??????? local d = touch:getDelta() ??????? plane:setPosition(x+d.x, y+d.y) ??? end ??? local function onTouchEnded(touch, event) ??? end ? ??? regTouch(scene, onTouchBegan, onTouchEnded, onTouchMoved) ? ??? ------------------- shoot ??? -- angle參數代表的發射角度,delta表示子彈發射的起始位置和英雄戰機的位置的偏移 ??? local function shootOne(angle, delta) ??????? cc.SimpleAudioEngine:getInstance():playEffect("m/bullet.wav") ? ??????? local bullet = cc.Sprite:create("Bullet.png") ??????? scene:addChild(bullet) ??????? local x, y = plane:getPosition() ??????? bullet:setPosition(x+delta.x, y+delta.y) ??????? bullet:setRotation(angle) ??????? ??????? -- math.rad(角度) 把角度轉換成弧度 ??????? local dx = math.sin( math.rad(angle) ) * winSize.height ??????? local dy = math.cos( math.rad(angle) ) * winSize.height ??????? local moveBy = cc.MoveBy:create(5, cc.p(dx, dy)) ??????? bullet:runAction(moveBy) ? ??????? -- 子彈保存在數組里 ??????? table.insert(bullets, bullet) ??? end ? ??? local function Shoot() ??????? local sizePlane = plane:getContentSize() ??????? if idx == 1 then ??????????? shootOne(0, cc.p(0, sizePlane.height/2)) ??????? elseif idx == 2 then ??????????? shootOne(0, cc.p(0, sizePlane.height/2)) ??????????? shootOne(0, cc.p(-sizePlane.width/4, sizePlane.height/4)) ??????????? shootOne(0, cc.p(sizePlane.width/4, sizePlane.height/4)) ??????? elseif idx == 3 then ??????????? shootOne(0, cc.p(0, sizePlane.height/2)) ??????????? shootOne(-30, cc.p(0, sizePlane.height/2)) ??????????? shootOne(30, cc.p(0, sizePlane.height/2)) ??????? elseif idx == 4 then ??????????? shootOne(0, cc.p(0, sizePlane.height/2)) ??????????? shootOne(180, cc.p(0, -sizePlane.height/2)) ??????????? shootOne(90, cc.p(sizePlane.width/2, 0)) ??????????? shootOne(270, cc.p(-sizePlane.width/2, 0)) ??????? elseif idx==5 then ??????????? shootOne(45, cc.p(0, 0)) ??????????? shootOne(45+90, cc.p(0, 0)) ??????????? shootOne(45+180, cc.p(0, 0)) ??????????? shootOne(45+270, cc.p(0, 0)) ??????? end ??? end ? ??? local function tickShoot() ??????? ??????? plane.curCD = plane.curCD + 1 ??????? if plane.curCD >= plane.cd then ??????????? Shoot() ??????????? plane.curCD = 0 ??????? end ??? end ? ??? local tickShootID = cc.Director:getInstance():getScheduler():scheduleScriptFunc(tickShoot, 0, false) ? ??? -- 檢查子彈是否飛出窗口外 ??? local function checkBulletAndEnemy() ??????? -- 得到子彈數量 ??????? local n = table.getn(bullets) ? ??????? for i = n, 1, -1 do ??????????? local bullet = bullets[i] ? ??????????? -- 判斷bullet是不是出了窗口 ??????????? local x, y = bullet:getPosition() ? ??????????? if x<0 or y<0 or x>winSize.width or y > winSize.height then ??????????????? bullet:removeFromParent() ??????????????? table.remove(bullets, i) -- 從bullets數組中,刪除下標為i的元素 ??????? ??????? cclog("bullet is out of window") ??????????? end ??????? end ? ??????? n = table.getn(enemys) ??????? for i = n, 1, -1 do ??????????? local enemy = enemys[i] ? ??????????? -- 判斷enemy是不是出了窗口 ??????????? local x, y = enemy:getPosition() ? ??????????? if y < -enemy:getContentSize().height/2 then ??????????????? enemy:removeFromParent() ??????????????? table.remove(enemys, i) -- 從enemys數組中,刪除下標為i的元素 ??????????????? ??????????? end ??????? end ??????? ??? end ? ??? ??? local tickCheckBullet = cc.Director:getInstance():getScheduler():scheduleScriptFunc(checkBulletAndEnemy, 0, false) ? ? ??? -- 產生敵機的定時器 ??? local function genEnemy(type) ??????? -- 創建敵機精靈,加入到數組,加入渲染樹 ??????? -- 增加敵機屬性 ??????? -- 隨機設置位置 ??????? local enemy = cc.Sprite:create("Enemy" .. type .. ".png") ??????? table.insert(enemys, enemy) ??????? scene:addChild(enemy) ? ??????? -- 敵軍飛機的額外屬性 ??????? local hp = {10, 30, 100} ??????? enemy.hp = hp[type] ? ??????? local score = {1000, 3000, 10000} ??????? enemy.score = score[type] ? ??????? local speed = {150, 100, 50} ??????? enemy.speed = speed[type] ??????? enemy.type = type ? ??????? -- 設置初始位置 ??????? local sizePlane = enemy:getContentSize() ??????? math.randomseed(os.time()) ??????? local x = math.random(sizePlane.width/2, winSize.width-sizePlane.width/2) ??????? local y = winSize.height + sizePlane.height/2 ??????? enemy:setPosition(x, y) ? ??????? -- 設置飛機飛行動作 ??????? local distance = winSize.height + sizePlane.height + 5 ??????? local moveBy = cc.MoveBy:create(distance*1.0/enemy.speed, cc.p(0, -distance)) ??????? enemy:runAction(moveBy) ? ??? end ? ??? local function genEnemy1() ??????? genEnemy(1) ??? end ??? local function genEnemy2() ??????? genEnemy(2) ??? end ??? local function genEnemy3() ??????? genEnemy(3) ??? end ? ??? local tickGenEnemy1 = cc.Director:getInstance():getScheduler():scheduleScriptFunc(genEnemy1, 1, false) ??? local tickGenEnemy2 = cc.Director:getInstance():getScheduler():scheduleScriptFunc(genEnemy2, 3, false) ??? local tickGenEnemy3 = cc.Director:getInstance():getScheduler():scheduleScriptFunc(genEnemy3, 10, false) ? ??? local function loadBoomAnimation() ??????? local spriteFrameCache = cc.SpriteFrameCache:getInstance() ??????? spriteFrameCache:addSpriteFrames("PFBoom.plist") ? ??????? -- CCArray* arr = CCArray:create() ??????? local spriteFrames = {} ??????? for i = 1, 18 do ??????????? local spriteFrame = spriteFrameCache:getSpriteFrame("Boom_" .. i .. ".png") ??????????? table.insert(spriteFrames, spriteFrame) ??????? end ? ??????? local animation = cc.Animation:createWithSpriteFrames(spriteFrames, 0.05) ??????? cc.AnimationCache:getInstance():addAnimation(animation, "ENEMYBOOM") ??? end ??? loadBoomAnimation() ? ??? local function removeEnemy(node, tab) ??????? node:removeFromParent() ??? end ? ??? local function enemyBoom(idx) ??????? local enemy = enemys[idx] ??????? ??????? cc.SimpleAudioEngine:getInstance():playEffect("m/enemy" .. enemy.type .. "_down.wav") ? ??????? -- 增加分數 ??????? local score = labelScore:getString() ??????? score = tonumber(score) + enemy.score ??????? labelScore:setString("" .. score) ? ??????? table.remove(enemys, idx) ? ??????? -- 執行爆炸動畫,然后再調用removeFromParent ??????? local animation = cc.AnimationCache:getInstance():getAnimation("ENEMYBOOM") ??????? local animate = cc.Animate:create(animation) ??????? local callfunc = cc.CallFunc:create(removeEnemy) ??????? local seq = cc.Sequence:create(animate, callfunc) ??????? enemy:runAction(seq) ? ??????? -- enemy:removeFromParent() ??? end ? ??? local function collision() ??????? local nEnemy = table.getn(enemys) ??????? local rcPlane = plane:getBoundingBox() ? ??????? for i = nEnemy, 1, -1 do ??????????? local enemy = enemys[i] ??????????? local rcEnemy = enemy:getBoundingBox() ??????????? local bEnemyBoom = false ? ??????????? -- 如果敵機和英雄戰機碰撞, rcEnemy, rcPlane ??????????? if cc.rectIntersectsRect(rcEnemy, rcPlane) then ??????????????? plane.hp = plane.hp - enemy.hp ??????????????? labelHP:setString("" .. plane.hp) ??????????????? if plane.hp <= 0 then ??????????????????? cc.Director:getInstance():replaceScene(SceneMenu()) ??????????????????? break ??????????????? end ? ??????????????? enemyBoom(i) ??????????????? bEnemyBoom = true ??????????? end ? ??????????? -- 跟子彈進行碰撞檢測 ??????????? if bEnemyBoom == false then ??????????????? local nBullet = table.getn(bullets) ??????????????? for j = nBullet, 1, -1 do ??????????????????? local bullet = bullets[j] ? ??????????????????? -- 如果子彈和敵機碰撞 ??????????????????? local ptBullet = cc.p( bullet:getPosition() ) ??????????????????? if cc.rectContainsPoint(rcEnemy, ptBullet) then ??????????????????????? bullet:removeFromParent() ??????????????????????? table.remove(bullets, j) ? ??????????????????????? enemy.hp = enemy.hp - plane.damage; ??????????????????????? if enemy.hp <= 0? then ??????????????????????????? enemyBoom(i) ??????????????????????????? break? -- 表示這個敵機不再和下一個子彈做碰撞檢測 ??????????????????????? end ??????????????????? end ??????????????? end ??????????? end ? ??????? end ??? end ??? local tickCollisionID = cc.Director:getInstance():getScheduler():scheduleScriptFunc(collision, 0, false) ? ??? local function Back() ??????? cc.Director:getInstance():replaceScene(SceneMenu()) ??? end ??? createBackMenu(scene, Back) ? ??? -- 注銷定時器 ??? local function onNodeEvent(event) ??????? if "enter" == event then ??????????? cclog("OnEnter") ??????????? cc.SimpleAudioEngine:getInstance():playMusic("m/game_music.wav", true) ??????? end ??????? if "exit" == event then ??????????? cc.SimpleAudioEngine:getInstance():stopMusic() ??????????? cc.Director:getInstance():getScheduler():unscheduleScriptEntry(tickShootID) ??????? ??? cc.Director:getInstance():getScheduler():unscheduleScriptEntry(tickCheckBullet) ??????? ??? cc.Director:getInstance():getScheduler():unscheduleScriptEntry(tickGenEnemy1) ??????? ??? cc.Director:getInstance():getScheduler():unscheduleScriptEntry(tickGenEnemy2) ??????? ??? cc.Director:getInstance():getScheduler():unscheduleScriptEntry(tickGenEnemy3) ??????? ??? cc.Director:getInstance():getScheduler():unscheduleScriptEntry(tickCollisionID) ??????? end ?? ?end ??? scene:registerScriptHandler(onNodeEvent) ? ? ??? return scene end |
| main.lua |
| --引入lua的方式是通過require require "Cocos2d" require "Cocos2dConstants" ? -- cclog 打印日志的方式 cclog = function(...) ??? print(string.format(...)) end ? -- for CCLuaEngine traceback??? lua中連接字符串的方式是通過 .. 實現的 function __G__TRACKBACK__(msg) ??? cclog("----------------------------------------") ??? cclog("LUA ERROR: " .. tostring(msg) .. "\n") ??? cclog(debug.traceback()) ??? cclog("----------------------------------------") ??? return msg end ? local function main() ??? collectgarbage("collect") ??? -- avoid memory leak ??? collectgarbage("setpause", 100) ??? collectgarbage("setstepmul", 5000) ? ??? -- initialize director? lua中定義局部變量的是通過local的方式 ??? local director = cc.Director:getInstance() ??? local glview = director:getOpenGLView() ??? if nil == glview then ??????? glview = cc.GLView:createWithRect('HelloLua', cc.rect(0,0,768/2,1280/2)) ??????? director:setOpenGLView(glview) ??? end ? ??? -- 設置設計分辨率,這個就是圖片的實際大小 ??? glview:setDesignResolutionSize(768, 1280, cc.ResolutionPolicy.NO_BORDER) ? ??? --turn on display FPS ??? director:setDisplayStats(true) ? ??? --set FPS. the default value is 1.0/60 if you don't call this ??? director:setAnimationInterval(1.0 / 60) ? ??? -- 設置加載的文件包 ??? cc.FileUtils:getInstance():addSearchPath("src") ??? cc.FileUtils:getInstance():addSearchPath("res") ??? ? ??? --support??? ??? local targetPlatform = cc.Application:getInstance():getTargetPlatform() ??? if (cc.PLATFORM_OS_IPHONE == targetPlatform) or (cc.PLATFORM_OS_IPAD == targetPlatform) or ?????? (cc.PLATFORM_OS_ANDROID == targetPlatform) or (cc.PLATFORM_OS_WINDOWS == targetPlatform) or ?????? (cc.PLATFORM_OS_MAC == targetPlatform) then ??????? cclog("result is ") ??????? --require('debugger')()? ??? end ??? ----------------------------------------------- ? ??? -- 自定義的文件的require必須在 addSearchPath之后,2.2.3沒有這個問題 ??? require "SceneStart" ??? cc.Director:getInstance():runWithScene(SceneStart()) ? end ? local status, msg = xpcall(main, __G__TRACKBACK__) if not status then ??? error(msg) end |
| 運行結果:
|
?
總結
以上是生活随笔為你收集整理的cocos2dx 3.2之Lua打飞机项目的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: u盘怎么安装启动网卡 U盘启动安装网卡方
- 下一篇: 开机进系统后蓝屏怎么解决方法 解决开机蓝