如何制作小游戏

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何制作小游戏相关的知识,希望对你有一定的参考价值。

教我制作小游戏,越详细越好

如何用DirectX制作2D游戏?
  DirectDraw组件是DirectX对2D的主要支持部分,参考文献“从头学习DirectDraw”、"DircetDraw c/c++ 使用指导(一)"、"载入位图文件到DirectDraw"。

如何使用DirectInput?
  DirectInput是DirectX API的输入控制组件,提供了操作硬件的底层接口,参考文献“DirectInput 鼠标编程入门”、“DirectInput 键盘编程入门”。

如何在游戏中显示文字?
  游戏中的文字显示一般由两种方法来实现,一种是通过调用系统APIs来进行绘制,另一种是通过自己管理字库进行绘制;这两种方法各有优缺,让我们看看它们如何实现的。系统APIs的使用参考"深入WINDOW字型",自处理字库绘制参考"点阵汉字显示"(关于自处理字体的说明,自处理字库就是通过某种存储方式将文字组织保存于文件中,然后在游戏中进行装载和绘制。)。

如何使用DirectSound?
  DirectSound是DirectX API的音频(waveaudio)组件之一,它可以提供快速的混音、硬件加速功能,并且可以直接访问相关设备,当然,最主要的是它提供的功能与现有的(?将来的呢?)设备驱动程序保持兼容性。参考文献“DirectSound”。

如何在游戏中播放一段电影?
  播放视频片断可以通过DirectShow来进行播放工作,参考文献"在VC中调用DirectShow全屏播放视频"。

如何在游戏中实现半透明效果?
  游戏中要进行(2D)图形的半透明效果主要就是通过alpha混合运算,参考文献"Alpha-Blending 技术简介"、"利用MMX优化64K色Alpha混合算法"。

如何把DirectX关联到VC中?
  我们要进行DirectX程序的编译就必须要有DirectX SDK库文件,此文件可以到微软或者本站获取,然后通过VC设置将其关联。下面说明了在VC6和VS.Net下的安装方法。
  VC6(英文版):选择菜单Tools->Options,打开Options对话框,选择Directions标签页,选择Include files项,在里面添加DirectX头文件的文件夹路径目录,同样,在Library files项中添加DirectX头文件的文件夹路径目录。
  VS.Net(中文版):选择菜单"工具->选项",打开选项对话框,打开Projects标签页,分别选择"包含文件"和"库文件"进行相应的路径添加即可。
注:VC在进行编译时,会根据排列顺序来进行库文件选取,假设有两个相同名字的库,VC会优先使用排列在前面的库文件。

VC编译DX程序出现"无法解析的外部符号"是怎么回事?
  这个错误经常出现在初学者要进行编译DirectX程序的时候,主要是因为没有将DX的库文件引用到工程中,这里需要注意,我们将DX SDK的路径设置到VC后,并不代表我们已设置好了DX SDK,在我们的DX工程中,我们还需要进行相应的设置操作,把我们所需要的库文件(DirectX SDK Library)加入到我们的工程中,要设置这个库文件有两个方法,一个是在你工程的编译选项中进行添加,另外一种可以通过代码的方法来添加(推荐)。
  命令行:#pragma comment( lib,"xxx.lib" )
  这个是VC的编译预处理指令,将其加在代码中即可。
  例如:#pragma comment( lib,"ddraw.lib" )  这句的意思是将ddraw.lib库加入到工程中进行编译。
注:此命令行不需要加分号(“;”)。
参考技术A 那要看你做什么形式小游戏了,以前我有一个,比较傻瓜的游戏制作软件,就是插入场景,选择动作,情节之类,然后会打包生成一个小游戏。不过记不得叫什么了。

要是实在想自己做,还有一个办法,就是你去找一些web的游戏代码,或者flash游戏源文件,自己进行修改,不要大变动,换个图片什么的。弄好了,也会有点成就感。百度一搜就能找到。 Gaara 2008-06-26 13:30 检举
参考技术B 那要看你做什么形式小游戏了,以前我有一个,比较傻瓜的游戏制作软件,就是插入场景,选择动作,情节之类,然后会打包生成一个小游戏。不过记不得叫什么了。

要是实在想自己做,还有一个办法,就是你去找一些web的游戏代码,或者flash游戏源文件,自己进行修改,不要大变动,换个图片什么的。弄好了,也会有点成就感。百度一搜就能找到。
参考技术C 用RPG MakerXP吧,那样你只要有一些语言基础就会制作出自己想要的游戏。
幻想游戏网~~很好的~~~
参考技术D 快点使用RPG MakerXP,哼哼哈嘿!!

如何通过 swiftUI 制作 2048 游戏 [关闭]

【中文标题】如何通过 swiftUI 制作 2048 游戏 [关闭]【英文标题】:how to make a 2048 game via swiftUI [closed] 【发布时间】:2020-06-11 10:46:33 【问题描述】:

我尝试通过 SwiftUI 制作 2048 游戏,我的游戏逻辑大部分是正确的,但是转场/动画是错误的,我不知道问题出在哪里以及如何解决它们! 游戏现在看起来像这样: the game acting gif

我有几个问题:

    看起来当磁贴移动到左侧或顶部时,过渡隐藏在灰色背景视图后面,我尝试将 ZIndex 添加到磁贴和背景,但它不起作用。 如何进行顺序转换,它应该首先从原始单元格移动,然后将自身从大到正常缩放 合并的过渡并非每次都像我预期的那样工作,实际上它只发生了几次

我的视图代码如下所示:

struct GameView: View 
    @ObservedObject var viewModel:GameViewModel

    var body: some View 
        let tap = DragGesture().onEnded(value in self.move(by: value))

        return GeometryReadergeo in
            ZStack
                RoundedRectangle(cornerRadius: 10.0).fill(Color(#colorLiteral(red: 0.719702065, green: 0.6819230318, blue: 0.6252140403, alpha: 1)))
                VStack
                    ForEach(0..<self.viewModel.gridSize)rowIndex in
                        HStack 
                            ForEach(self.viewModel.tiles[rowIndex])tile in
                                    TileView(tile:tile)
                            
                        
                    
                
                .padding()
            
            .gesture(tap)
            .frame(width: geo.size.width, height: geo.size.width, alignment: .center)

        



    

    func move(by value:DragGesture.Value)

        withAnimation(Animation.easeInOut.speed(2))
            if abs(value.translation.height) > abs(value.translation.width)
                if value.translation.height > 30 
                    self.viewModel.move(by:GameModel.Direction.down)
                else if value.translation.height < -30
                    self.viewModel.move(by:GameModel.Direction.up)
                
            else
                if value.translation.width > 30 
                    self.viewModel.move(by:GameModel.Direction.right)
                else if value.translation.width < -30
                    self.viewModel.move(by:GameModel.Direction.left)
                
            
        

    




struct TileView: View 
    var tile:GameModel.Tile

    var body: some View 
        GeometryReader  geometry in
            self.body(for: geometry.size)
        
    

    @ViewBuilder
    private func body(for size:CGSize) -> some View 
        ZStack
            RoundedRectangle(cornerRadius: 10.0).fill(Color(#colorLiteral(red: 0.794301331, green: 0.7563138604, blue: 0.7084676027, alpha: 1)))
            if(tile.value != 0)
                ZStack
                    RoundedRectangle(cornerRadius: 10.0).fill(tile.bgColor)
                    Text(String(tile.value)).font(Font.system(size: fontSize(for: size,in: tile.value))).foregroundColor(tile.fontColor)
                
                .transition(transition(for: size))
                .zIndex(100)
            
        .zIndex(98)

    


    private let cornerRadius:CGFloat = 10.0
    private let edgeLineWidth:CGFloat = 3

    private func fontSize(for size: CGSize, in value:Int) -> CGFloat
        size.width * 0.7 / CGFloat(String(value).count)
    

    private func transition(for size:CGSize) -> AnyTransition
        var transition:AnyTransition
        if let mergedFrom = tile.mergedFrom
            let perviousTile = mergedFrom[0]
            let offset = CGSize(width: CGFloat(perviousTile.x - tile.x )*size.width, height: CGFloat(perviousTile.y - tile.y )*size.height)
            transition = AnyTransition.offset(offset).combined(with: AnyTransition.scale(scale: 2))
        else
            if let previousPosition = tile.previousPosition 
                let offset = CGSize(width: CGFloat(previousPosition.x - tile.x )*size.width, height: CGFloat(previousPosition.y - tile.y )*size.height)
                transition = AnyTransition.offset(offset)
            else
                transition = AnyTransition.scale
            
        
        return AnyTransition.asymmetric(insertion: transition.animation(.easeInOut), removal: .identity)
    


及型号代码:

struct GameModel 
    private(set) var tiles: Array<Array<Tile>>
    private(set) var gridSize:Int



    init(gridSize:Int)
        self.gridSize = gridSize
        tiles = Array<Array<Tile>>()
        for i in 0..<gridSize
            var row = Array<Tile>()
            for j in 0..<gridSize
                row.append(Tile(x: j, y: i))
            
            tiles.append(row)
        
        generateTile()
        generateTile()
    

    private mutating func generateTile()
        var emptyPositionArr:Array<(x:Int,y:Int)> = []
        for rowIndex in 0..<gridSize
            for colIndex in 0..<gridSize
                if(tiles[rowIndex][colIndex].value == 0)
                    emptyPositionArr.append((x:colIndex,y:rowIndex))
                
            
        
        if let randomPos = emptyPositionArr.randomElement() 
            let randomValue = Bool.random() ? 2 : 4
            tiles[randomPos.y][randomPos.x].value = randomValue
        else
            print("No remaining spaces!")
        
    

    mutating func prepareTiles()
        for y in 0..<gridSize
            for x in 0..<gridSize
                if(tiles[y][x].value != 0)
                    tiles[y][x].mergedFrom = nil
//                    tiles[y][x].savePosition()
                
            
        
    


    mutating func move(by direction:Direction)
        let vector:(x:Int,y:Int) = getVector(by: direction)
        var moved = false
        prepareTiles()

        var col:Array<Int> = []
        var row:Array<Int> = []
        for i in 0...3
            col.append(i)
            row.append(i)
        
        if(vector.x == 1)
            col = col.reversed()
        
        if(vector.y == 1)
            row = row.reversed()
        
        for y in row
            for x in col
                let cell = Cell(x: x, y: y)
                var newCell:Cell
                let tile = tiles[y][x]
                if(tile.value != 0)
                    let positions = findFarthestPosition(cell: cell, vector: vector)

                    if let next = cellCotent(at: positions.next), next.value == tile.value, next.mergedFrom == nil
                        let merged = Tile(x: next.x, y: next.y, value: tile.value * 2, mergedFrom: [tile,next])
                        insertTile(tile: merged)
                        removeTile(tile: tile)
                        newCell = Cell(x: next.x, y: next.y)
                    else
                        removeTile(tile: tile)
                        insertTile(tile: Tile(x: positions.farthest.x, y: positions.farthest.y, value: tile.value,previousPosition: cell))

                        newCell = Cell(x: positions.farthest.x, y: positions.farthest.y)
                    

                    if(newCell.x != cell.x  || newCell.y != cell.y)
                        moved = true
                    

                
            
        

        if(moved)
            generateTile()
        

    

    func findFarthestPosition(cell: Cell,vector:(x:Int,y:Int)) -> (farthest:Cell,next:Cell)
        var previous:Cell
        var currentcell = cell
        repeat
            previous = currentcell
            currentcell = Cell(x: previous.x + vector.x, y: previous.y + vector.y)
        while(withinBounds(cell: currentcell) && cellAvailable(cell: currentcell) )
        return (previous,currentcell)
    

    func getVector(by direction:Direction) -> (x:Int,y:Int)
        var x = 0;
        var y = 0;
        switch direction 
        case .down:
            y =  1
        case .up:
            y = -1
        case .left:
            x = -1
        case .right:
            x = 1
        
        return (x:x,y:y)
    

    //MARK: - Cell

    struct Cell 
        var x:Int
        var y:Int
    

    func cellCotent(at cell:Cell) -> Tile? 
        if(withinBounds(cell: cell))
            return tiles[cell.y][cell.x]
        else
            return nil
        
    

    func cellAvailable (cell:Cell) -> Bool 
        if(withinBounds(cell: cell))
            return tiles[cell.y][cell.x].value == 0
        else
            return false
        
    

    func withinBounds(cell:Cell) -> Bool 
        return cell.x >= 0 && cell.x < self.gridSize && cell.y >= 0 && cell.y < gridSize
    

    mutating func insertTile(tile:Tile)
        tiles[tile.y][tile.x] = tile
    

    mutating func removeTile(tile:Tile)
        tiles[tile.y][tile.x].value = 0
        tiles[tile.y][tile.x].mergedFrom = nil
        tiles[tile.y][tile.x].previousPosition = nil
    

    mutating func moveTile(tile:Tile,cell:Cell)
        tiles[tile.y][tile.x].value = 0
        tiles[tile.y][tile.x].mergedFrom = nil
        tiles[cell.y][cell.x] = tile

    

    //MARK: - Tile

    struct Tile: Identifiable
        var x:Int
        var y:Int
        var value:Int = 0
        var mergedFrom:Array<Tile>?
        var previousPosition:Cell?
        var bgColor:Color
            get
                if(value > 2048)
                    return Color(.black)
                else
                    return  GameModel.ColorMap[value]!
            
        
        var fontColor:Color
            get
                if(value <= 4)
                    return Color(.black)
                else
                    return Color(.white)
                
            
        

        var id: Int
            get
                (y*10) + x
            
        

        mutating func savePosition()
            self.previousPosition = Cell(x: x, y: y)
        

    

    static let ColorMap =  [
        0:Color(#colorLiteral(red: 0.8036968112, green: 0.7560353875, blue: 0.7039339542, alpha: 1)),
        2: Color(#colorLiteral(red: 0.9316522479, green: 0.8934505582, blue: 0.8544340134, alpha: 1)),
        4: Color(#colorLiteral(red: 0.9296537042, green: 0.8780228496, blue: 0.7861451507, alpha: 1)),
        8: Color(#colorLiteral(red: 0.9504186511, green: 0.6943461895, blue: 0.4723204374, alpha: 1)),
        16: Color(#colorLiteral(red: 0.9621869922, green: 0.6018956304, blue: 0.3936881721, alpha: 1)),
        32:Color(#colorLiteral(red: 0.9640850425, green: 0.49890697, blue: 0.3777080476, alpha: 1)),
        64: Color(#colorLiteral(red: 0.9669782519, green: 0.406899184, blue: 0.2450104952, alpha: 1)),
        128: Color(#colorLiteral(red: 0.9315031767, green: 0.8115276694, blue: 0.4460085034, alpha: 1)),
        256: Color(#colorLiteral(red: 0.9288312197, green: 0.7997121811, blue: 0.3823960423, alpha: 1)),
        512: Color(#colorLiteral(red: 0.9315162301, green: 0.783490479, blue: 0.3152971864, alpha: 1)),
        1024: Color(#colorLiteral(red: 0.9308142066, green: 0.7592952847, blue: 0.179728806, alpha: 1)),
        2048: Color(#colorLiteral(red: 0.9308142066, green: 0.7592952847, blue: 0.179728806, alpha: 1)),
    ]

    enum Direction 
        case up
        case down
        case left
        case right
    


视图模型:

class GameViewModel: ObservableObject 
    @Published private(set) var model: GameModel =  GameViewModel.createGame()

    private static func createGame () -> GameModel 
        return GameModel(gridSize: 4)
    

    //MARK: - Access to the model
    var tiles:Array<Array<GameModel.Tile>> 
        model.tiles
    

    var gridSize:Int 
        model.gridSize
    

    //MARK: - Intent(s)

    func move(by direction:GameModel.Direction)
        model.move(by: direction)
    


我的源代码上传到github,请大家帮帮我

【问题讨论】:

请阅读***.com/help/how-to-ask -> 问题应该只有一个问题,而不是很多 【参考方案1】:

发生这种情况是因为图块被移动到其 Z 位置低于“挡道”行的位置

您可以将背景与图块分开,因此您可以确保图块始终位于顶部:

var body: some View 
    let tap = DragGesture().onEnded(value in self.move(by: value))

    return GeometryReadergeo in
        ZStack
            RoundedRectangle(cornerRadius: 10.0).fill(Color(#colorLiteral(red: 0.719702065, green: 0.6819230318, blue: 0.6252140403, alpha: 1)))
            VStack
                ForEach(0..<self.viewModel.gridSize) rowIndex in
                    HStack 
                        ForEach(0..<self.viewModel.gridSize) columnIndex in
                            RoundedRectangle(cornerRadius: 10.0).fill(Color(#colorLiteral(red: 0.794301331, green: 0.7563138604, blue: 0.7084676027, alpha: 1))).transition(.identity)
                        
                    
                
            
            .padding()
            VStack
                ForEach(0..<self.viewModel.gridSize)rowIndex in
                    HStack 
                        ForEach(self.viewModel.tiles[rowIndex])tile in
                            TileView(tile:tile)
                        
                    
                
            
            .padding()
        
        .gesture(tap)
        .frame(width: geo.size.width, height: geo.size.width, alignment: .center)
    

【讨论】:

以上是关于如何制作小游戏的主要内容,如果未能解决你的问题,请参考以下文章

如何制作小游戏,我想制作一个小游戏,该怎样做呢?

如何制作手机游戏

求教如何在Unity中为2D游戏制作技能特效

在 ROBLOX 上,我如何制作小游戏脚本? [关闭]

如何使用 Unity制作微信小游戏,微信小游戏制作方案 最新完整详细教程来袭持续更新

如何使用 Unity制作微信小游戏,微信小游戏制作方案 最新完整详细教程来袭持续更新