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 ...
随机推荐
- “百度杯”CTF比赛 九月场_Code(PhpStorm)
题目在i春秋ctf大本营 打开链接是一张图片,审查元素发现关键词base64,图片的内容都以base64加密后的形式呈现,查看url形式,应该是一个文件读取的漏洞 这里我们可以采用url/index. ...
- phpcmsV9.5.8 后台拿shell
参考url:https://xianzhi.aliyun.com/forum/read/1507.html poc:index.php??m=content&c=content&a=p ...
- codefroces 297E Mystic Carvings
problem:一个圆上依次有1~2*n的数字.每个数字都有且只有另一个数字与他相连.选出三条线,使得每条线的两端之间隔的最少点(只包括被选择的6个点)的个数相等.输入输出格式输入格式: The fi ...
- [Ioi2011]ricehub
Description 乡间有一条笔直而长的路称为“米道”.沿着这条米道上 R 块稻田,每块稻田的坐标均 为一个 1 到 L 之间(含 1 和 L)的整数.这些稻田按照坐标以不减的顺序给出,即对于 0 ...
- 【线段树】【BZOJ1798】【AHOI2009】维护序列
还是那个学弟@lher出的丧题之一. 链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1798 题意简析:就是题目啊... 解题思路:显然是线段树 ...
- [APIO/ctsc2007]
A.风铃 给一棵二叉树,叶子结点是玩具,为使你的弟弟满意,你需要选一个满足下面两个条件的风铃: (1) 所有的玩具都在同一层(也就是说,每个玩具到天花板之间的杆的个数是一样的)或至多相差一层.(2) ...
- Amazon新一代云端关系数据库Aurora(上)
本文由 网易云发布. 在2017年5月芝加哥举办的世界顶级数据库会议SIGMOD/PODS上,作为全球最大的公有云服务提供商,Amazon首次系统的总结 了新一代云端关系数据库Aurora的设计实现 ...
- sqlserver 取日期年份月份
select convert(varchar(10),datepart(YYYY,a.fssj)) as years,--得到年份convert(varchar(10),datepart(mm,a.f ...
- filter和listener的生命周期
filter(过滤器)和listener(监听器)的生命周期 老实说 生命周期要是说成作用的时间范围我会理解的更好 filter package com.javaweb.filter; import ...
- angularjs+ionic的app端分页和条件
做app项目积分商城的商品列表需要分页显示 实现: ionic滚动条:ion-scroll 用于创建一个可滚动的容器. 附:菜鸟教程:http://www.runoob.com/ionic/ionic ...