Cocea编写的一款3D地牢游戏例程

2023-12-21 16:50

本文主要是介绍Cocea编写的一款3D地牢游戏例程,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

2019独角兽企业重金招聘Python工程师标准>>> hot3.png

# Cocea编写的一款3D地牢游戏例程

简单介绍:就是一款用 Codea 编写的第一人称视角的 3D 迷宫游戏,你可以用你的 iPad 在这个基础上学习 3D 编程,边修改边查看效果。

这个游戏说明用 Codea 可以编出各种类型的游戏来,唯一的限制是我们的想象力!


作者:@Ignatz

原始文档链接:
http://codea.io/talk/discussion/5746/huge-3d-dungeon-updates

Git代码链接:
https://gist.github.com/dermotbalson/ae547d75672ddfbaa06e

代码中使用到的贴图资源百度网盘地址:

http://pan.baidu.com/s/1dDcSU9V

纹理贴图:

@x2


其中也包括作者关于 Codea 编程的一些电子书(简单英文):

http://pan.baidu.com/s/1bnzX7Vx

3D in Codea

http://pan.baidu.com/s/10FBMu

http://pan.baidu.com/s/1hqxL6V6

http://pan.baidu.com/s/1sjsJ0kd

http://pan.baidu.com/s/1i3vbDPF

http://pan.baidu.com/s/1dDByQ0D

截图:

代码:

--# Main
--Dungeon ver 1.0--navigation
--touch left 1/3 of screen to turn left, right 1/3 of screen to turn right
--touch top 1/3 of screen to move forward, bottom 1/3 of screen to go backwards
--touch centre of screen to stop
--touching multiple times speeds up--BUGS
--the navigation could probably be improved
--it is possible to walk through some walls (maybe my map showing which tiles are occupied, is faulty)
--also I think I have a hole in a wall somewheredisplayMode(FULLSCREEN)
supportedOrientations(LANDSCAPE_ANY)function setup()FPS=60M=ReadMap() --see Map tab--set up scene--pass texture, texture scale (0.05 means reduce image by 95%), tile width, and wall heightS=Scene("Dropbox:3D-walls",0.05,M.width,M.height)mapp={} --table which will hold the position of all the walls for collision avoidancefor i=1,M.size.x do mapp[i]={} end --initialise--add walls to mesh--add roomsfor i=1,#M.rooms dofor j,w in pairs(M.rooms[i].walls) doS:AddSideWall(w,mapp)endend--add corridorsfor i=1,#M.corr dofor j,w in pairs(M.corr[i].walls) doS:AddSideWall(w,mapp)endend--images--these are added differently, see Billboard class images={}for u,i in pairs(M.images) doimages[#images+1]=Billboard(i,M.width,M.height,mapp)end--create separate "scene" for floor/ceiling because it has different textureF=Scene("Dropbox:3D-gravel1s",0.05,M.width,M.height)F:AddFloorCeiling(M.floor)--create map we can show on screenMapScale=6 --scaleMapTrans=75 --transparencyMapImg=image(M.size.x*MapScale,M.size.y*MapScale)setContext(MapImg)rectMode(CENTER)pushStyle()fill(255,255,255,MapTrans)for i=1,M.size.x dofor j=1,M.size.y doif mapp[i][j]==1 then rect(i*MapScale,j*MapScale,MapScale,MapScale)endendendpopStyle()setContext()--starting position--deduct 0.5 from x and z so we start in the middle of the specified tile--concert from tile units to pixels--z is made negative, if you don't know why, you should go read up on 3D to avoid great confusionpos=vec3((M.startPos.x-0.5)*M.width,M.startPos.y*M.height,-(M.startPos.z-0.5)*M.width)--player settingsangle=0 --player orientationturnAngle=3 --how much player turns when screen is touched--for smoother turning, when you tap to turn, targetAngle changes, and angle will move towards it..targetAngle=0 ----..the speed with which angle changesangleChange=0.5--"tall" is the height of the camera (sorry about variable names)tall=M.startPos.y--get the light rangerange=M.range--set the flicker as % of total light radiusflicker=0.3--this is added to current position to set the camera directionlook=vec3(0,tall,-1000)lookDist=1000 --this seems to duplicate the look var, need to investigate--velocityvel=vec3(0,0,0) --current speedspeed=0--height of the light we are holdinglightHeight=vec3(0,M.height*0.25,0)--set position of map buttonmapButtonRadius=25mapButton=vec2(WIDTH-mapButtonRadius-5,mapButtonRadius+5)mapShowing=false--create map buttonmapButtonImg=image(mapButtonRadius*2,mapButtonRadius*2)setContext(mapButtonImg)pushStyle()fill(255,255,0,100)ellipse(mapButtonImg.width/2,mapButtonImg.height/2,mapButtonRadius*2)popStyle()setContext()fill(255)fontSize(12)
endfunction draw()background(150)FPS=0.95*FPS+0.05/DeltaTime --FPS is geometric averageperspective()--move towards target angle if we are turningif targetAngle~=angle thenif targetAngle<angle then angle=angle-angleChange else angle=angle+angleChange endChangeVel()end--camera poscamera(pos.x,pos.y,pos.z,pos.x+look.x,look.y,pos.z+look.z)--if we aren't walking into a wall, we can moveif CanMove(pos+vel,mapp) then pos=pos+vel else speed=0 end--set flicker radius using noiselocal u=range*(1+flicker*noise(ElapsedTime))--draw all the wallsS:draw(pos+lightHeight,u) --pass light position and flicker level--draw the floor and roofF:draw(pos+lightHeight,u)--draw billboard images (they are rotated first)for a,i in pairs(images) do i:draw(pos,u)end--draw FPS on screenortho()viewMatrix(matrix())text("FPS="..math.floor(FPS),50,50)--draw map buttonsprite(mapButtonImg,mapButton.x,mapButton.y)DrawMap(pos)
end--check if the square the player is in contains a wall
--there is a bug either in this or in my mapp table because I can 
--sometimes walk through walls :(
function CanMove(v,m) local a=PlayerTile(v)if m[a.x][a.y]==1 then return false else return true end
endfunction PlayerTile(v)return vec2(math.floor(v.x/M.width+1),math.floor(-v.z/M.width+1))
end--handles player movement
function touched(t)--check for map touch firstif t.state==BEGAN thenif  vec2(t.x,t.y):dist(mapButton)<mapButtonRadius thenmapShowing=not mapShowingelseif t.tapCount==2 thenif t.x<WIDTH/3 then targetAngle=targetAngle-90   elseif t.x>WIDTH*2/3 then targetAngle=targetAngle+90end    else       if t.x<WIDTH/3 then targetAngle=targetAngle-turnAngle     elseif t.x>WIDTH*2/3 then targetAngle=targetAngle+turnAngleelseif t.y<HEIGHT/3 then speed=speed-M.walkChangeVel()elseif t.y>HEIGHT*2/3 then speed=speed+M.walk ChangeVel()elseif vec2(WIDTH/2,HEIGHT/2):dist(vec2(t.x,t.y))<150 then speed=0targetAngle=angleChangeVel()endendend
endfunction DrawMap(p)if not mapShowing then return endlocal margin=8local x,y=WIDTH-MapImg.width-margin,mapButtonRadius*2+marginsprite(MapImg,x+MapImg.width/2,y+MapImg.height/2)local a=PlayerTile(p)pushStyle()fill(255,255,0,MapTrans*2)ellipse(x+p.x/M.width*MapScale,y-p.z/M.width*MapScale,MapScale)popStyle()
endfunction ChangeVel()local a=math.rad(angle)local s,c=math.sin(a),math.cos(a)vel.x,vel.z=speed*s,-speed*clook.x,look.z=lookDist*s,-lookDist*c
end--handles billboarded images
Billboard=class()--t is table of image,x,y,z in tile units, then ambient light fraction
--w,h are map.width,map.height, m is mapp table listing all the things the player can't walk through
--we will add the images to this table
function Billboard:init(t,w,h,m)  self.m=mesh()self.width,self.height=w,hm[t[2]][t[4]]=1 --mark this tie as occupiedlocal tex --for imageif type(t[1])=="string" then tex=readImage(t[1]) else tex=t[1] end--set position in centre of tileself.x,self.y,self.z=(t[2]-0.5)*self.width,t[3]*self.height,-(t[4]-0.5)*self.widthself.angle=0 --for rotating to face the playerself.count=0 --on;y rotate every few frames, use this counter--add image to meshself.m:addRect(0,0,tex.width*self.y/tex.height,self.y) self.m.texture=tex--billboards have their own slightly modified shader to handle transparent pixelsself.m.shader=shader(TransTileShader.vertexShader,TransTileShader.fragmentShader)self.m.shader.lightbase=t[5] --set ambient lightendfunction Billboard:draw(p,r) --p is player position, r is current light rangeself.m.shader.pos=p self.m.shader.range=r--adjust rotation every 10 framesself.count=self.count+1if self.count%10==0 then--rotate to face playerlocal dx,dz=self.x-p.x,self.z-p.zself.angle=math.deg(math.atan(dx/-dz))endpushMatrix()translate(self.x,self.y/2,self.z)rotate(-self.angle,0,1,0)self.m.shader.mModel = modelMatrix()self.m:draw()popMatrix()
end--main class for handling map wals, floor, roof
Scene=class()function Scene:init(tex,s,w,h) --tex is image, s is image scaling, w,h are tile size and wall heightself.m=mesh()if type(tex)=="string" then tex=readImage(tex) endself.iw,self.ih=tex.width,tex.heightself.width,self.height=w,hself.v,self.t={},{}self.s=s or 1self.m.texture=texself.m.shader=shader(TileShader.vertexShader,TileShader.fragmentShader)
end--v1,v2,v3,v4 are positions of the four wall corners
function Scene:AddWall(v1,v2,v3,v4)--figure out tex coords, ie which way the wall is pointinglocal d=v2-v1local dx,dyif d.x~=0 then dx=d.x elseif d.y~=0 then dx=d.y else dx=d.z endd=v3-v2if d.x~=0 then dy=d.x elseif d.y~=0 then dy=d.y else dy=d.z end--next bit is important for tiling, calculate texture upper limit as width of mesh / size of scaled imagelocal tx1,tx2=0,math.abs(dx)/self.iw/self.s local ty1,ty2=0,math.abs(dy)/self.ih/self.s--verticeslocal n=#self.vself.v[n+1],self.v[n+2],self.v[n+3],self.v[n+4],self.v[n+5],self.v[n+6]=v1,v2,v3,v3,v4,v1--add to existing mesh vertices which are stored in a "buffer" local b=self.m:buffer("position")b:resize(n+6)for i=1,#self.v do b[i]=self.v[i] end--now the texture mappingslocal n=#self.tself.t[n+1],self.t[n+2],self.t[n+3],self.t[n+4],self.t[n+5],self.t[n+6]=vec2(tx1,ty1),vec2(tx2,ty1),vec2(tx2,ty2),vec2(tx2,ty2),vec2(tx1,ty2),vec2(tx1,ty1)--add to texture bufferlocal b=self.m:buffer("texCoord")b:resize(n+6)for i=1,#self.t do b[i]=self.t[i] endself.m:setColors(color(255))
end--calculates corner vecs for a wall, given a vec4 containing (x1,z1,x2,z2)
function Scene:AddSideWall(v,m) --m is mapp table listing tiles containing wallslocal x1,y1,z1=(v.x-0.5)*self.width,0,-(v.y-0.5)*self.widthlocal x2,y2,z2=(v.z-0.5)*self.width,self.height,-(v.w-0.5)*self.widthself:AddWall(vec3(x1,y1,z1),vec3(x2,y1,z2),vec3(x2,y2,z2),vec3(x1,y2,z1))--update mapp table to show these tiles are occupiedif m thenfor i=math.min(v.x,v.z),math.max(v.x,v.z) dom[i][v.y]=1endfor i=math.min(v.y,v.w),math.max(v.y,v.w) do m[v.x][i]=1endend
end--simpified version of AddSideWall, only this wall is horizontal
function Scene:AddFloorCeiling(v)local x1,z1=(v.x-0.5)*self.width,-(v.y-0.5)*self.widthlocal x2,z2=(v.z-0.5)*self.width,-(v.w-0.5)*self.widthself:AddWall(vec3(x1,0,z1),vec3(x2,0,z1),vec3(x2,0,z2),vec3(x1,0,z2))self:AddWall(vec3(x1,self.height,z1),vec3(x2,self.height,z1),vec3(x2,self.height,z2),vec3(x1,self.height,z2))
end--not used
function Scene:AddLight(v)self.m.shader.light=vec3(v.x*self.width,v.y*self.height,v.z*self.width)
endfunction Scene:draw(p,r)self.m.shader.pos=pself.m.shader.range=rself.m.shader.mModel = modelMatrix()self.m:draw()
end--this shader used by the walls, floor, roof
TileShader = {
vertexShader = [[
uniform mat4 modelViewProjection;
uniform mat4 mModel;
attribute vec4 position;
attribute vec4 color;
attribute vec2 texCoord;
varying lowp vec4 vColor;
varying highp vec2 vTexCoord;
varying highp vec4 vPosition;void main()
{vColor = color;vTexCoord = texCoord;gl_Position = modelViewProjection * position;vPosition = mModel * position; //needed to set light intensity
}]],
fragmentShader = [[
precision highp float;
uniform lowp sampler2D texture;
uniform lowp float range;  //light range
uniform lowp vec3 pos;  //position of player
varying lowp vec4 vColor;
varying highp vec2 vTexCoord;
varying highp vec4 vPosition; //position of current pixel         void main()
{    float f=max(0.,1.0-length( pos - vPosition.xyz ) / range); //light reduces linearly with distance//next is the magic line of code that tiles the image across areas of any size//it is multiplied by the light intensity calculated abovelowp vec4 col = f*texture2D( texture, vec2(mod(vTexCoord.x,1.0), mod(vTexCoord.y,1.0)));col.a=1.0;gl_FragColor =col;
}
]]
}--this shader is used by the images
--the only difference is that transparent pixes are discarded
TransTileShader = {
vertexShader = [[
uniform mat4 modelViewProjection;
uniform mat4 mModel;
attribute vec4 position;
attribute vec4 color;
attribute vec2 texCoord;
varying lowp vec4 vColor;
varying highp vec2 vTexCoord;
varying highp vec4 vPosition;void main()
{vColor = color;vTexCoord = texCoord;gl_Position = modelViewProjection * position;vPosition = mModel * position;
}]],
fragmentShader = [[
precision highp float;
uniform lowp sampler2D texture;
uniform lowp float range;
uniform lowp float lightbase;
uniform lowp vec3 pos;
varying lowp vec4 vColor;
varying highp vec2 vTexCoord;
varying highp vec4 vPosition;          void main()
{    lowp vec4 col = texture2D( texture, vTexCoord );if (col.a==0.0) discard; //this is the only differenceelse {//lightbase below is the ambient light of this object, gives it a glow if you want onefloat f=max(0.,1.0-length( pos - vPosition.xyz ) / range)+lightbase;col = col*f;col.a=1.0;gl_FragColor=col;}
}
]]
}
--# Map
--Dungeon map--this map is organised as a table
--the map is a rectangular grid of squares
--image here: http://i1303.photobucket.com/albums/ag142/ignatz_mouse/dungeon_zpsc89352fc.png--Thinking I would have to cull (ie ony draw stuff directly around the player), I organised the map
--to have corridors between all the rooms. This made it easier to say "if you are in room X, also draw
--corridors "Y and Z". It proved unnecessary - so far. 
--anyway, that is why I have organised the walls by room, and separatey for rooms and corridors--LOCATION OF IMAGES REQUIRED
--https://www.dropbox.com/sh/i7stxdfcnnh8azx/AAByAiTG7oswE7nczwZj4pxUa?dl=0function ReadMap()local map={}map.width=10  --number of pixels per square (not a good variable name!)map.height=20 --height of walls in pixelsmap.size=vec2(82,114) --number of tiles wide and deepmap.startPos=vec3(72,0.5,8) --starting tilemap.walk=0.2  --speed change (pixels/sec) when you touch screenmap.range=100 --range of light, in pixelsmap.rooms,map.corr={},{} --rooms and corridors stored separately--load the map coordinateslocal m,c=map.rooms,map.corrfor i=1,23 do m[i]={} endfor i=1,30 do c[i]={} end--the rooms and corr tables have provision for wall and neighbour settings--I'm only using wall settings, as explained above--room 1--each wall is stored in a vec4 = (x1,z1,x2,z2) in tile units--no need for a y value, we know each wall goes from 0 to map.heightm[1].walls={vec4(64,11,75,11),vec4(75,11,75,4),vec4(61,4,75,4),vec4(61,10,61,4)}--m[1].neighbours={m.corr1}	--this was where I was going to specify neighboursm[2].walls={vec4(41,10,56,10),vec4(56,13,56,10),vec4(40,19,40,13),vec4(40,19,53,19),vec4(56,19,56,16)}m[3].walls={vec4(21,16,21,1),vec4(21,1,30,1),vec4(30,10,30,1),vec4(30,20,30,13),vec4(21,20,30,20),vec4(21,20,21,19)}	m[4].walls={vec4(32,21,34,21),vec4(32,27,32,21),vec4(32,36,32,30),vec4(38,21,40,21),vec4(40,24,40,21),vec4(40,36,40,27),vec4(35,36,40,36)}m[5].walls={vec4(13,33,13,21),vec4(16,21,22,21),vec4(22,27,22,21),vec4(22,39,22,30),vec4(13,39,22,39),vec4(13,39,13,36)}m[6].walls={vec4(8,28,11,28),vec4(11,28,11,21),vec4(5,21,11,21),vec4(5,28,5,21),vec4(5,28,6,28)}m[7].walls={vec4(2,39,2,30),vec4(2,30,6,30),vec4(8,30,11,30),vec4(11,33,11,30),vec4(11,39,11,36),vec4(2,39,11,39)}m[8].walls={vec4(50,39,50,30),vec4(50,30,59,30),vec4(59,45,59,30),vec4(50,45,59,45),vec4(50,45,50,42)}m[9].walls={vec4(23,48,23,47),vec4(23,48,29,48),vec4(32,48,37,48),vec4(37,48,37,41),vec4(35,41,37,41),vec4(23,41,32,41),vec4(23,44,23,41)}m[10].walls={vec4(10,56,16,56),vec4(10,56,10,41),vec4(10,41,19,41),vec4(19,44,19,41),vec4(19,56,19,47)}m[11].walls={vec4(34,68,34,62),vec4(34,68,39,68),vec4(34,59,34,52),vec4(34,52,48,52),vec4(48,59,48,52),vec4(48,68,48,62),vec4(43,68,48,68)}m[12].walls={vec4(61,56,61,50),vec4(61,56,66,56),vec4(69,56,72,56),vec4(72,56,72,41),vec4(67,41,72,41),vec4(61,41,64,41),vec4(61,47,61,41)}m[13].walls={vec4(13,85,19,85),vec4(13,85,13,76),vec4(13,76,16,76),vec4(19,76,27,76),vec4(27,85,27,76),vec4(21,85,27,85)}m[14].walls={vec4(29,91,29,81),vec4(29,81,32,81),vec4(35,81,39,81),vec4(43,81,45,81),vec4(45,87,45,81),vec4(37,91,45,91),vec4(29,91,34,91)}m[15].walls={vec4(50,93,50,91),vec4(50,93,58,93),vec4(50,87,50,84),vec4(50,84,55,84),vec4(59,90,59,84)}m[16].walls={vec4(50,76,50,64),vec4(50,64,61,64),vec4(61,70,61,64),vec4(61,79,61,73),vec4(59,79,61,79),vec4(51,79,55,79)}m[17].walls={vec4(74,99,74,93),vec4(74,99,82,99),vec4(82,99,82,84),vec4(74,84,82,84),vec4(74,90,74,84)}m[18].walls={vec4(50,105,50,99),vec4(50,105,59,105),vec4(59,105,59,96),vec4(51,96,59,96)}m[19].walls={vec4(28,114,28,107),vec4(28,107,34,107),vec4(28,114,34,114),vec4(34,114,34,110),vec4(34,108,34,107)}m[20].walls={vec4(36,111,36,110),vec4(36,111,48,111),vec4(48,111,48,101),vec4(45,101,48,101),vec4(36,101,42,101),vec4(36,108,36,101)}m[21].walls={vec4(63,114,63,104),vec4(63,114,77,114),vec4(77,114,77,104),vec4(69,104,77,104),vec4(63,104,66,104)}m[22].walls={vec4(23,69,23,65),vec4(23,69,27,69),vec4(29,69,30,69),vec4(30,69,30,65),vec4(26,65,30,65),vec4(23,65,24,65)}   m[23].walls={vec4(21,63,24,63),vec4(26,63,27,63),vec4(27,63,27,58),vec4(21,58,27,58),vec4(21,60,21,58)}--corridors nowc[1].walls={vec4(56,13,61, 13),vec4(61,13,61, 10),vec4(56,16,64, 16),vec4(64,16,64, 11)}c[2].walls={vec4(38,13,40, 13),vec4(38,21,38, 13),vec4(34,21,34, 13),vec4(30,13,34, 13),vec4(30,10,41, 10)}	c[3].walls={vec4(16,19,21,19),vec4(16,21,16,19),vec4(13,16,21,16),vec4(13,21,13,16)}c[4].walls={vec4(53,24,53,19),vec4(56,24,56,19),vec4(40,24,53,24),vec4(56,24,67,24),vec4(40,27,64,27),vec4(64,41,64,27),vec4(67,41,67,24)}c[5].walls={vec4(8,30,8,28),vec4(6,30,6,28)}c[6].walls={vec4(22,27,32,27),vec4(22,30,32,30)}c[7].walls={vec4(32,41,32,36),vec4(35,41,35,36)}c[8].walls={vec4(19,47,23,47),vec4(19,44,23,44)}c[9].walls={vec4(29,62,29,48),vec4(32,59,32,48),vec4(29,62,34,62),vec4(32,59,34,59)}c[10].walls={vec4(48,59,53,59),vec4(48,62,56,62),vec4(56,62,56,50),vec4(53,59,53,50),vec4(56,50,61,50),vec4(45,50,53,50),vec4(45,50,45,39),vec4(45,39,50,39),vec4(48,42,50,42),vec4(48,47,48,42),vec4(48,47,61,47)}   c[11].walls={vec4(66,70,66,56),vec4(69,77,69,56),vec4(66,77,66,73),vec4(61,73,66,73),vec4(61,70,66,70)}    c[12].walls={vec4(66,90,66,78),vec4(69,90,69,79)}c[13].walls={vec4(69,93,74,93),vec4(69,90,74,90)}   c[14].walls={vec4(58,93,66,93),vec4(59,90,66,90)}  c[15].walls={vec4(45,91,50,91),vec4(45,87,50,87)}   c[16].walls={vec4(19,88,19,85),vec4(21,88,21,85)}c[17].walls={vec4(43,79,51,79),vec4(43,76,50,76)}c[18].walls={vec4(16,76,16,56),vec4(19,60,19,56),vec4(19,70,19,63),vec4(19,76,19,73)}c[19].walls={vec4(19,63,21,63),vec4(19,60,21,60)}c[20].walls={vec4(19,73,32,73),vec4(19,70,27,70),vec4(29,70,35,70),vec4(35,81,35,70),vec4(32,81,32,73)}c[21].walls={vec4(39,81,39,68),vec4(43,81,43,79),vec4(43,76,43,68)}c[22].walls={vec4(34,99,34,91),vec4(34,99,42,99),vec4(37,96,50,96),vec4(45,99,50,99),vec4(37,96,42,96)}c[23].walls={vec4(42,101,42,99),vec4(45,101,45,99)}c[24].walls={vec4(34,110,36,110),vec4(34,108,36,108)}c[25].walls={vec4(66,104,66,93),vec4(69,104,69,93)}c[26].walls={vec4(55,84,55,79),vec4(59,84,59,79)}c[27].walls={vec4(69,79,72,79),vec4(69,77,72,77)}c[28].walls={vec4(24,65,24,63),vec4(26,65,26,63)}c[29].walls={vec4(11,36,13,36),vec4(11,33,13,33)}c[30].walls={vec4(27,70,27,69),vec4(29,70,29,69)}--floor coords, wil be used for roof toomap.floor=vec4(2,1,82,114)--set of images to be billboarded--table contains image, x, y, z, s--where x,z are tile positions, y is fraction of map.height--and s is ambient lighting, 0 for none, 1 for bright, this property makes them glow in the darkmap.images={{readImage("Dropbox:Gargoyle"),53,0.5,16,0.2},{readImage("Dropbox:Gargoyle"),53,0.5,14,0.2},{readImage("Dropbox:Buddha1"),34,0.5,23,0.2},{readImage("Dropbox:Buddha2"),36,0.5,11,0.4}}return map
end



转载于:https://my.oschina.net/freeblues/blog/325858

这篇关于Cocea编写的一款3D地牢游戏例程的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/520761

相关文章

使用Java编写一个文件批量重命名工具

《使用Java编写一个文件批量重命名工具》这篇文章主要为大家详细介绍了如何使用Java编写一个文件批量重命名工具,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录背景处理1. 文件夹检查与遍历2. 批量重命名3. 输出配置代码片段完整代码背景在开发移动应用时,UI设计通常会提供不

Python开发围棋游戏的实例代码(实现全部功能)

《Python开发围棋游戏的实例代码(实现全部功能)》围棋是一种古老而复杂的策略棋类游戏,起源于中国,已有超过2500年的历史,本文介绍了如何用Python开发一个简单的围棋游戏,实例代码涵盖了游戏的... 目录1. 围棋游戏概述1.1 游戏规则1.2 游戏设计思路2. 环境准备3. 创建棋盘3.1 棋盘类

无人叉车3d激光slam多房间建图定位异常处理方案-墙体画线地图切分方案

墙体画线地图切分方案 针对问题:墙体两侧特征混淆误匹配,导致建图和定位偏差,表现为过门跳变、外月台走歪等 ·解决思路:预期的根治方案IGICP需要较长时间完成上线,先使用切分地图的工程化方案,即墙体两侧切分为不同地图,在某一侧只使用该侧地图进行定位 方案思路 切分原理:切分地图基于关键帧位置,而非点云。 理论基础:光照是直线的,一帧点云必定只能照射到墙的一侧,无法同时照到两侧实践考虑:关

国产游戏崛起:技术革新与文化自信的双重推动

近年来,国产游戏行业发展迅猛,技术水平和作品质量均得到了显著提升。特别是以《黑神话:悟空》为代表的一系列优秀作品,成功打破了过去中国游戏市场以手游和网游为主的局限,向全球玩家展示了中国在单机游戏领域的实力与潜力。随着中国开发者在画面渲染、物理引擎、AI 技术和服务器架构等方面取得了显著进展,国产游戏正逐步赢得国际市场的认可。然而,面对全球游戏行业的激烈竞争,国产游戏技术依然面临诸多挑战,未来的

如何编写Linux PCIe设备驱动器 之二

如何编写Linux PCIe设备驱动器 之二 功能(capability)集功能(capability)APIs通过pci_bus_read_config完成功能存取功能APIs参数pos常量值PCI功能结构 PCI功能IDMSI功能电源功率管理功能 功能(capability)集 功能(capability)APIs int pcie_capability_read_wo

MiniGPT-3D, 首个高效的3D点云大语言模型,仅需一张RTX3090显卡,训练一天时间,已开源

项目主页:https://tangyuan96.github.io/minigpt_3d_project_page/ 代码:https://github.com/TangYuan96/MiniGPT-3D 论文:https://arxiv.org/pdf/2405.01413 MiniGPT-3D在多个任务上取得了SoTA,被ACM MM2024接收,只拥有47.8M的可训练参数,在一张RTX

火柴游戏java版

代码 /*** 火柴游戏* <p>* <li>有24根火柴</li>* <li>组成 A + B = C 等式</li>* <li>总共有多少种适合方式?</li>* <br>* <h>分析:</h>* <li>除去"+"、"="四根,最多可用火柴根数20根。</li>* <li>全部用两根组合成"1",最大数值为1111。使用枚举法,A和B范围在0~1111,C为A+B。判断</li>** @

国产游戏行业的崛起与挑战:技术创新引领未来

国产游戏行业的崛起与挑战:技术创新引领未来 近年来,国产游戏行业蓬勃发展,技术水平不断提升,许多优秀作品在国际市场上崭露头角。从画面渲染到物理引擎,从AI技术到服务器架构,国产游戏已实现质的飞跃。然而,面对全球游戏市场的激烈竞争,国产游戏技术仍然面临诸多挑战。本文将探讨这些挑战,并展望未来的机遇,深入分析IT技术的创新将如何推动行业发展。 国产游戏技术现状 国产游戏在画面渲染、物理引擎、AI

SAM2POINT:以zero-shot且快速的方式将任何 3D 视频分割为视频

摘要 我们介绍 SAM2POINT,这是一种采用 Segment Anything Model 2 (SAM 2) 进行零样本和快速 3D 分割的初步探索。 SAM2POINT 将任何 3D 数据解释为一系列多向视频,并利用 SAM 2 进行 3D 空间分割,无需进一步训练或 2D-3D 投影。 我们的框架支持各种提示类型,包括 3D 点、框和掩模,并且可以泛化到不同的场景,例如 3D 对象、室

一款支持同一个屏幕界面同时播放多个视频的视频播放软件

GridPlayer 是一款基于 VLC 的免费开源跨平台多视频同步播放工具,支持在一块屏幕上同时播放多个视频。其主要功能包括: 多视频播放:用户可以在一个窗口中同时播放任意数量的视频,数量仅受硬件性能限制。支持多种格式和流媒体:GridPlayer 支持所有由 VLC 支持的视频格式以及流媒体 URL(如 m3u8 链接)。自定义网格布局:用户可以配置播放器的网格布局,以适应不同的观看需求。硬