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打飞机项目的更多相关文章
- cocos2dx 3.1.1移植安卓apk (lua交叉编译器项目 mac环境)
cocos2dx 3.1.1 lua项目安卓交叉编译 mac环境 本文基于ant,sdk,ndk,adt等软件和环境已经事前设置好 1\新建项目 在mac的终端下输入命令: cocos new t ...
- Lua + win 10 + vs2017的运行环境和创建cocos2dx 3.17的lua项目(亲测)
转:https://blog.csdn.net/maoye198602102339/article/details/82047920 不管用什么引擎写游戏,脚本语言是少不了要接触的! 首先,我说的 ...
- 【COCOS2DX-LUA 脚本开发之一】在Cocos2dX游戏中使用Lua脚本进行游戏开发(基础篇)并介绍脚本在游戏中详细用途!
[COCOS2DX-LUA 脚本开发之一]在Cocos2dX游戏中使用Lua脚本进行游戏开发(基础篇)并介绍脚本在游戏中详细用途! 分类: [Cocos2dx Lua 脚本开发 ] 2012-04-1 ...
- Cocos2d-x 3.1.1 Lua实例-AccelerometerTest(重力加速计)
Cocos2d-x 3.1.1 Lua实例-AccelerometerTest(重力加速计) 本篇博客介绍Cocos2d-x的第一个实例--重力加速计測试.效果图(注:这里无法模拟重力感应): --[ ...
- Cocos2d-x 3.1.1 Lua演示样例 ActionsProgressTest(进度条)
Cocos2d-x 3.1.1 Lua演示样例 ActionsProgressTest(进度条) 本篇博客介绍Cocos2d-x中的进度条动画,进度条涉及以下几个重要的类和方法,笔者来给大家具体解说一 ...
- Cocos2d-x 3.1.1 Lua演示样例 ActionManagerTest(动作管理)
Cocos2d-x 3.1.1 Lua演示样例 ActionManagerTest(动作管理) 本篇博客介绍Cocos2d-x的动作管理样例,这个样例展示了Cocos2d-x的几个动作: MoveTo ...
- cocos2dx打飞机项目笔记一:项目结构介绍
最近在学习cocos2dx引擎,版本是2.1.3,开发环境是win7 + vs2010,模仿微信打飞机游戏,开发中参考了 csdn 偶尔e网事 的系列文章:http://blog.csdn.net/c ...
- cocos2dx+lua编译Android项目
一.简单介绍 cocos2dx版本号:3.2 二.问题及解决方式 1.为项目开启Native支持,把项目转为C++项目. 1>.项目开启C++ Native支持,操作例如以下图 watermar ...
- cocos2d-x(十二)Lua开发飞机大战-7-加入敌机
Lua本是一门面向过程的解释性语言.但在开发过程中有很多人还是习惯于面向对象编程.在Lua中我们能够使用table模拟类.只是写起来不太爽(特别是在继承一些C++类的时候).通过查看演示样例.发现co ...
随机推荐
- [SDOI 2015]序列统计
Description 题库链接 给出集合 \(S\) ,元素都是小于 \(M\) 的非负整数.问能够生成出多少个长度为 \(N\) 的数列 \(A\) ,数列中的每个数都属于集合 \(S\) ,并且 ...
- [HNOI 2003]激光炸弹
Description 一种新型的激光炸弹,可以摧毁一个边长为R的正方形内的所有的目标.现在地图上有n个目标,用整数,表示目标在地图上的位置,每个目标都有一个价值.激光炸弹的投放是通过卫星定位的,但其 ...
- codefroces 946G Almost Increasing Array
Description给你一个长度为$n$的序列$A$.现在准许你删除任意一个数,删除之后需要修改最小的次数使序列单调递增.问最小次数.$1≤n≤200000$ExamplesInput55 4 3 ...
- [JLOI2011]飞行路线
Description Alice和Bob现在要乘飞机旅行,他们选择了一家相对便宜的航空公司.该航空公司一共在n个城市设有业务,设这些城市分别标记为0到n-1,一共有m种航线,每种航线连接两个城市,并 ...
- bzoj 5285: [Hnoi2018]寻宝游戏
Description Solution 把输入的 \(n\) 个二进制数看作一个大小为 \(n*m\) 的矩阵 把每一列压成一个二进制数,其中最高位是最下面的元素 然后就有了 \(m\) 个二进制数 ...
- ●codeforces 553E Kyoya and Train
题链: http://codeforces.com/problemset/problem/623/E 题解: FFT,DP 题意: 一个有向图,给出每条边的起点u,终点v,费用c,以及花费每种时间的概 ...
- [BZOJ]3110 K大数查询(ZJOI2013)
这大概是唯一一道小C重写了4次的题目. 姿势不对的树套树(Fail) → 分块(Fail) → 整体二分(Succeed) → 树套树(Succeed). 让小C写点心得静静. Description ...
- JSP 基本语法
1 JSP 的由来 servlet产生后,存在很大的问题,为了表现页面的效果,需要输出大量的HTML 语句,表现为一个个字符串,不仅利于开发,也不利于后期的维护,由此产生了JSP.主要用于将Servl ...
- 基于SSE4和多核编程的电子相册的实现
基于SSE4和多核编程的电子相册的实现 摘要:电子相册中前后两张图片的切换会产生淡入淡出效果,而且切换过程中需要大量的中间计算过程,而SSE4和多核编程技术能够有效加快中间的计算过程,有效减少图片 ...
- 在 TensorFlow 中实现文本分类的卷积神经网络
在TensorFlow中实现文本分类的卷积神经网络 Github提供了完整的代码: https://github.com/dennybritz/cnn-text-classification-tf 在 ...