您的位置:首页 > 移动开发 > Cocos引擎

Cocos2d-X引擎+Lua语言俄罗斯方块的制作及基本逻辑编写(上)

2017-10-08 17:43 344 查看

一、游戏区域准备

(根据上一篇博客http://blog.csdn.net/ZY_cat/article/details/78157227搭建游戏环境。)

①首先解决格子到最终屏幕位置的转换问题。

打开src->app目录下新建一个Common.lua文件。用notepad++打开,编码格式转为UTF-8无编码格式。下面为Common.lua具体代码

cGridSize = 32 --每个方块是32个像素

cScenWidth = 8 + 2  --场景的宽度,单位是格子,

cScenHeight = 18 --场景的高度,

function Grid2Pos(x,y)  --把格子转成最终渲染的位置函数

local visibleSize = cc.Direct:getInstance():getVisibleSize()

local origin = cc.Director:getInstance():getVisibleOrigin()

local finalX = origin.x + visibleSize.width*0.5 + x*cGridSize - cScenWidth/2*cGridSize

local finalY = origin.y + visibleSize.height*0.5 + y*cGridSize - cScenHeight/2*cGridSize

return finalX,finalY
end


②游戏场景

同样打开src->app目录下新建一个Scene.lua文件。用notepad++打开,编码格式转为UTF-8无编码格式。下面为Scene.lua具体代码

require "app.Common" x,y

-- 8 * 18

local Scene = class("Scene")

local function makeKey(x,y)
return x*1000 + y
end

function Scene:ctor(node) --Scene的构造函数

self.map = {}

for x = 0,cSceneWidth -1 do

for y = 0,cSceneHight -1 do

local posX,posY = Grid2Pos(x,y)
local sp = cc.Sprite:create("box.png")  --没有图片
sp:setPosition(posX,posY)
node:addChild(sp)

local visible = (x == 0 or x==cSceneWidth-1)or y==0

sp:setVisible(visible)

self.map[makeKey(x,y)]=sp  --一维数组通过制造key,把它变成线性的坐标

end

end

end

function Scene:ClearLine(y)

for x = 1,cSceneWidth -2 do
self:Set(x,y,false)
end

end

function Scene:Clear()

for y = 1,cSceneHight - 1 do
self:ClearLine(y)
end
end

function Scene:Set(x,y,value)

local sp = self.map[makeKey(x,y)]
if sp == nil then
return
end

sp:setVisible(value)

end

function Scene:Get(x,y)

local sp = self.map[makeKey(x,y)]
if sp == nil then
return
end

return sp:isVisible()
end


③主逻辑场景

引用之前写好的Scene

local Scene = require "app.Scene"

local MainScene = class("MainScene",function()
return display.newScene("Scene")
end)

function MainScene():ctor

end

function MainScene:onEnter()

self.scene = Scene.new(self)

end

function MainScene:onExit()

end

return MainScene


④数据化方块

搭建好了游戏场景,现在开始数据化方块。俄罗斯方块有很多形状,每个形状还会旋转。这里我们用一个4*4的数组,正好以(2,2)这个点旋转。

举以下两个例子。(其他的自己完善~)这里我们设置一个变量innitoffset,因为其他型方块第一行都是有1的,如果把方块放在底部的时候它会吸住底部,直线型方块第一行是空白的,为了让它不那么怪异,就让它这个方块偏转一下吸住底部。后面的逻辑就是操作这一堆数据。

local cBlockArray = {
{
initoffset =1,
{
{1,1,1,0}, --1表示有,0表示有
{0,1,0,0},-- ***
{0,0,0,0},--  *
{0,0,0,0},
},

{
{0,1,0,0}, --1表示有,0表示有
{1,1,0,0},-- *
{0,1,0,0},--**
{0,0,0,0},-- *
},
}


⑤方块变形

申明方块类

local Block = class("Block")


每个方块的初始偏移整个屏幕宽度的一半-3

local InitXOffset = cSceneWidth/2 - 3


编写Block的构造函数,传入scene,index是选哪个方块

function Block:ctor(scene,index)

self.x = InitXOffset
self.y = cSceneHeight

local offset = cBlockArray[index].initOffset

if offset then
self.y = self.y + offset --lua 无自加符
end

self.scene = scene
self.index = index
self.trans = 1

end


遍历方块函数

local function IterateBlock(index,trans,callback)

local transArray = cBlockArray[index] --取一种形状
local eachBlock = transArray[trans] --变化

for y=1,#eachBlock do

local xdata = eachBlock[y]

for x=1,#data do  --# 字符串取长度,table取数量

local data = xdata[x]

if not callback(x,y,data~=0)then
return false
end

end

end

return true
end


放置方块到游戏场景

function RawPlace(index,trans,scene,newX,newY) --放置方块到游戏场景

local result = {}

if IterateBlock(index,trans,function(x,y,b))

if b then

local finalX = newX + x
local finalY = newY - y

if scene:Get(finalX,finalY)then --在场景中找能否放这个方块,如果不能就返回false
return false
end

table.insert(result,{x=finalX,y=finalY})

end

return true
end )then

for k,v in ipairs(result) do
scene:Set(v.x,v.y,true)
end

return true

end


方块移动

function Block:Move(deltaX,deltaY) --方块移动

self:Clear()

local x = self.x + deltaX
local y = self.y + deltaY

if RawPlace(self.index,self.trans,self.scene,x,y) then
self.x = x
self.y = y
return true

else
self.Place()
return false

end

end


方块变形–旋转

function Block:Rotate() --方块变形,旋转

local offset = cBlockArray[self.index].initOffset --剔除不符合条件
if offset and self.y == 0 then
return
end

self.Clear()

local transArray = cBlockArray[self.index]

local trans = self.trans + 1

if trans >#transArray then
trans = 1
end

if RawPlace(self.index,trans,self.scene,self.x,self.y)then
self.trans = trans

else
self:Place()
end

end


把方块直接放上去

function Block:Place()

return RawPlace(self.index,self.trans,self.scene,self.x,self.y)

end

function Block:Clear()

IterateBlock(self.index,self.trans,function(x,y,b))
local finalX = self.x + x
local finalY = self.y +    if b then
self.scene:Set(finalX,finalY,false)
end

ren true
end)

end


调节分辨率,宽960,高640,固定高

CC_DESIGN_RESOLUTION = {
width = 960,
height = 640,
autoscale = "FIXED_HEIGHT",
callback = function(framesize)
local ratio = framesize.width / framesize.height
if ratio <= 1.34 then
-- iPad 768*1024(1536*2048) is 4:3 screen
return {autoscale = "FIXED_WIDTH"}
end
end
}


(注:因为实验室项目开发,本人也还在学习中,本文为imooc徐波老师课程笔记)

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: