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打飞机项目的更多相关文章

  1. cocos2dx 3.1.1移植安卓apk (lua交叉编译器项目 mac环境)

    cocos2dx 3.1.1   lua项目安卓交叉编译 mac环境 本文基于ant,sdk,ndk,adt等软件和环境已经事前设置好 1\新建项目 在mac的终端下输入命令: cocos new t ...

  2. Lua + win 10 + vs2017的运行环境和创建cocos2dx 3.17的lua项目(亲测)

    转:https://blog.csdn.net/maoye198602102339/article/details/82047920   不管用什么引擎写游戏,脚本语言是少不了要接触的! 首先,我说的 ...

  3. 【COCOS2DX-LUA 脚本开发之一】在Cocos2dX游戏中使用Lua脚本进行游戏开发(基础篇)并介绍脚本在游戏中详细用途!

    [COCOS2DX-LUA 脚本开发之一]在Cocos2dX游戏中使用Lua脚本进行游戏开发(基础篇)并介绍脚本在游戏中详细用途! 分类: [Cocos2dx Lua 脚本开发 ] 2012-04-1 ...

  4. Cocos2d-x 3.1.1 Lua实例-AccelerometerTest(重力加速计)

    Cocos2d-x 3.1.1 Lua实例-AccelerometerTest(重力加速计) 本篇博客介绍Cocos2d-x的第一个实例--重力加速计測试.效果图(注:这里无法模拟重力感应): --[ ...

  5. Cocos2d-x 3.1.1 Lua演示样例 ActionsProgressTest(进度条)

    Cocos2d-x 3.1.1 Lua演示样例 ActionsProgressTest(进度条) 本篇博客介绍Cocos2d-x中的进度条动画,进度条涉及以下几个重要的类和方法,笔者来给大家具体解说一 ...

  6. Cocos2d-x 3.1.1 Lua演示样例 ActionManagerTest(动作管理)

    Cocos2d-x 3.1.1 Lua演示样例 ActionManagerTest(动作管理) 本篇博客介绍Cocos2d-x的动作管理样例,这个样例展示了Cocos2d-x的几个动作: MoveTo ...

  7. cocos2dx打飞机项目笔记一:项目结构介绍

    最近在学习cocos2dx引擎,版本是2.1.3,开发环境是win7 + vs2010,模仿微信打飞机游戏,开发中参考了 csdn 偶尔e网事 的系列文章:http://blog.csdn.net/c ...

  8. cocos2dx+lua编译Android项目

    一.简单介绍 cocos2dx版本号:3.2 二.问题及解决方式 1.为项目开启Native支持,把项目转为C++项目. 1>.项目开启C++ Native支持,操作例如以下图 watermar ...

  9. cocos2d-x(十二)Lua开发飞机大战-7-加入敌机

    Lua本是一门面向过程的解释性语言.但在开发过程中有很多人还是习惯于面向对象编程.在Lua中我们能够使用table模拟类.只是写起来不太爽(特别是在继承一些C++类的时候).通过查看演示样例.发现co ...

随机推荐

  1. [SDOI 2015]序列统计

    Description 题库链接 给出集合 \(S\) ,元素都是小于 \(M\) 的非负整数.问能够生成出多少个长度为 \(N\) 的数列 \(A\) ,数列中的每个数都属于集合 \(S\) ,并且 ...

  2. [HNOI 2003]激光炸弹

    Description 一种新型的激光炸弹,可以摧毁一个边长为R的正方形内的所有的目标.现在地图上有n个目标,用整数,表示目标在地图上的位置,每个目标都有一个价值.激光炸弹的投放是通过卫星定位的,但其 ...

  3. codefroces 946G Almost Increasing Array

    Description给你一个长度为$n$的序列$A$.现在准许你删除任意一个数,删除之后需要修改最小的次数使序列单调递增.问最小次数.$1≤n≤200000$ExamplesInput55 4 3 ...

  4. [JLOI2011]飞行路线

    Description Alice和Bob现在要乘飞机旅行,他们选择了一家相对便宜的航空公司.该航空公司一共在n个城市设有业务,设这些城市分别标记为0到n-1,一共有m种航线,每种航线连接两个城市,并 ...

  5. bzoj 5285: [Hnoi2018]寻宝游戏

    Description Solution 把输入的 \(n\) 个二进制数看作一个大小为 \(n*m\) 的矩阵 把每一列压成一个二进制数,其中最高位是最下面的元素 然后就有了 \(m\) 个二进制数 ...

  6. ●codeforces 553E Kyoya and Train

    题链: http://codeforces.com/problemset/problem/623/E 题解: FFT,DP 题意: 一个有向图,给出每条边的起点u,终点v,费用c,以及花费每种时间的概 ...

  7. [BZOJ]3110 K大数查询(ZJOI2013)

    这大概是唯一一道小C重写了4次的题目. 姿势不对的树套树(Fail) → 分块(Fail) → 整体二分(Succeed) → 树套树(Succeed). 让小C写点心得静静. Description ...

  8. JSP 基本语法

    1 JSP 的由来 servlet产生后,存在很大的问题,为了表现页面的效果,需要输出大量的HTML 语句,表现为一个个字符串,不仅利于开发,也不利于后期的维护,由此产生了JSP.主要用于将Servl ...

  9. 基于SSE4和多核编程的电子相册的实现

    基于SSE4和多核编程的电子相册的实现   摘要:电子相册中前后两张图片的切换会产生淡入淡出效果,而且切换过程中需要大量的中间计算过程,而SSE4和多核编程技术能够有效加快中间的计算过程,有效减少图片 ...

  10. 在 TensorFlow 中实现文本分类的卷积神经网络

    在TensorFlow中实现文本分类的卷积神经网络 Github提供了完整的代码: https://github.com/dennybritz/cnn-text-classification-tf 在 ...