Scala天天酷跑小游戏

本文详细介绍了如何实现《天天酷跑》的登录、注册功能,以及玩家角色的移动、跳跃、碰撞检测,包括与障碍物和金币的交互。通过代码片段展示了人物类(Person)、障碍物(Obstruct)和金币(Money)的定义,以及背景绘制和游戏循环的实现。
摘要由CSDN通过智能技术生成

需求分析:

  1. 实现《天天酷跑》的核心逻辑,该游戏具有登录、注册、玩家操作、结束等功能。
  2. 注册模块:需要玩家身份信息为:用户名 密码 昵称 邮箱
  3. 登录模块:需要玩家信息为:用户名 和 密码
  4. 玩家(Person)功能:跳跃up(y坐标的改变),右移功能(right),左移功能left(修 改x的坐 标),判断玩家是否越界的功能。玩家具有得分、跑酷距离、生命值属性。
    初始位置坐标为(x,y),补充自由下落功能(注意y坐标的临界点),login方法,注册方法,(建议可以通过在控制台内输入w a d 或者 2 6 8来控制玩家的坐标移动)
  5. 障碍物:障碍物从右向左自动进场,y坐标固定,x坐标左移,个数随机, 间隔 某个时间段 会创建一个障碍物,障碍物的越界问题
  6. 逻辑层代码:实现玩家和障碍物碰撞的逻辑,结束的逻辑

代码结构

class Person(){
  val width=2  //2*2的矩阵
  val height=2
  var locationX=9  //初始位置(9,1)
  var locationY=1
  var jumpCount=0 // 最多允许二段跳
  var HP=5
  var score:Int=0
  var speedX=0  //单位char/s
  var speedY=0
  def commandP():Unit={} //读入w,a,d移动指令
  def move():Unit={}  //计算位移
  def crashed(o:obstruct):Int={}  //判断撞击障碍物
  def crashMoney(m:money):Int={} //判断撞击金币
}
class obstruct(){
  var obstructList=ListBuffer[ListBuffer[Int]]()// [0:“x”,1:"y",2:"speedX",3:"speedY",4:"weight",5:"height"],障碍物列表
  def move(): Unit ={}
  def appendObject(): Unit ={}
  def deleteObject(): Unit ={}
}
class money(){
  val length:Int=1
  val weight:Int=1
  val point=20000 //一个金币两万分
  var moneyList=ListBuffer[ListBuffer[Int]]()// [0:“x”,1:"y",2:"speedX",3:"speedY"] //金币列表
  def move(): Unit ={}
  def appendObject(): Unit ={}
  def deleteObject(): Unit ={}
}
class background() {
  val height:Int=30 //100*30字符位组成的游戏界面
  val width:Int=100
  def draw(o:obstruct,p:Person,m:money): Unit = {} //ui界面函数
}
class gameThread extends Thread {
  var p=new Person()
  var o=new obstruct()
  var m=new money()
  var bg=new background()
  var timecount:Float=0 //单位:s
  var gamemode=1 //游戏开始
  override def run() {}
}
class account(){
  var currentName=""
  var account=ListBuffer[Map[String,String]](Map("用户名"->"root","密码"->"000","昵称"->"god","邮箱"->"8848@qq.com"))
  def register(){}
  def search(username:String,password:String) :Boolean ={}
  def login(): Boolean ={}
}
object game {  //主类
  def main(args:Array[String]):Unit = {}
}

详细代码

package _4_14实验三
import scala.io.StdIn
import scala.collection.mutable.Map
import scala.collection.mutable.ListBuffer
class Person(){
  val width=2  //2*2的矩阵
  val height=2
  var locationX=9  //初始位置(9,1)
  var locationY=1
  var jumpCount=0 // 最多允许二段跳
  var HP=5
  var score:Int=0
  var speedX=0  //单位char/s
  var speedY=0
  def commandP(): Unit ={
    val command = StdIn.readLine()
    command match {
      case "w" => {
        if(jumpCount<2){
          speedY=15 //向上腾起
          jumpCount+=1
        }
      }
      case "a" => {
        speedX=(-15)
      }
      case "d" => {
        speedX=15
      }
      case _ =>{
        //无操作
      }
    }
  }
  def move(): Unit ={
    locationX=locationX+(speedX.toFloat*0.5).toInt //det(x)=速度v*det(t),小区间内近似看作匀速运动
    locationY=locationY+(speedY.toFloat*0.5).toInt
    println("person(x,y):"+locationX,locationY)
    if(locationY<0){
      //println("越界了")
      locationY=0
      speedY=0
      jumpCount=0
    } //越界处理
    if(locationX>100){locationX=100}
    if(locationX<0){locationX=0}
    //区间结束后对加速度做出改变
    speedY=speedY+((-10.0)*0.5).toInt  //det(v)=加速度a*det(t)
    speedX=0
  }
  def crashed(o:obstruct): Int ={
    println("剩余血量: ",HP)
    for(item <- o.obstructList){
      val centerDistanceX=((locationX+width/2)-(item(0)+item(4)/2)).abs
      val centerDistanceY=((locationY+height/2)-(item(1)+item(5)/2)).abs
      if( (centerDistanceX<(width/2+item(4)/2)) && (centerDistanceY<(height/2+item(5)/2)) ){
        //两个中心点间的x,y方向距离都小于AB边长和的一半 相交
        println("发生碰撞")
        HP-=1
        if(HP<=0){
          println("碰撞五次,游戏结束!")
          return 0
        }  //结束游戏
        else {
          return 1
        }
      }
    }
    return 1
  }
  def crashMoney(m:money): Int ={
    for(item <- m.moneyList){
      if(item(0)>=locationX && item(0)<locationX+width && item(1)>=locationY && item(1)<locationY+height){
        println("吃到金币")
        return m.point
      }
    }
    return 0
  }
}
class obstruct(){
  var obstructList=ListBuffer[ListBuffer[Int]]()// [0:“x”,1:"y",2:"speedX",3:"speedY",4:"weight",5:"height"]
  def move(): Unit ={
    var i=0
    while(i<obstructList.length){
      obstructList(i)(0)+=(obstructList(i)(2)*0.5).toInt //det(x)=速度v*det(t),小区间内近似看作匀速运动 障碍物只做横向运动
      i+=1
    }
  }
  def appendObject(): Unit ={
    if(scala.util.Random.nextInt(10)>=7){ //每0.5秒有30%概率生成一个障碍物
      val randomY=scala.util.Random.nextInt(30)
      //val randomSpeed= -(scala.util.Random.nextInt(10)+10)
      val randomWidth=scala.util.Random.nextInt(5)+4  //宽度随机1-3
      val randomHeight=scala.util.Random.nextInt(10)+5    //高度随机2-4
      obstructList.append(ListBuffer(100,randomY,-15,0,randomWidth,randomHeight))
    }
  }
  def deleteObject(): Unit ={
    var i=0
    while(i<obstructList.length){
      if(obstructList(i)(0)<=0) { //越界,删除障碍物
        obstructList.remove(i)
      }
      i+=1
    }
  }
}
class money(){
  val length:Int=1
  val weight:Int=1
  val point=20000 //一个金币两万分
  var moneyList=ListBuffer[ListBuffer[Int]]()// [0:“x”,1:"y",2:"speedX",3:"speedY"]
  def move(): Unit ={
    var i=0
    while(i<moneyList.length){
      moneyList(i)(0)+=(moneyList(i)(2)*0.5).toInt //det(x)=速度v*det(t),小区间内近似看作匀速运动 障碍物只做横向运动
      i+=1
    }
  }
  def appendObject(): Unit ={
    if(scala.util.Random.nextInt(100)>=65){ //每0.5秒有40%概率生成一个金币
      val randomY=scala.util.Random.nextInt(3)
      moneyList.append(ListBuffer(100,randomY,-15,0))
    }
  }
  def deleteObject(): Unit ={
    var i=0
    while(i<moneyList.length){
      if(moneyList(i)(0)<=0) { //越界,删除金币
        moneyList.remove(i)
      }
      i+=1
    }
  }
}
class background() {
  val height:Int=30 //100*30字符位组成的游戏界面
  val width:Int=100
  def draw(o:obstruct,p:Person,m:money): Unit = {
    var i = 0
    var j = 0
    var CharList=ListBuffer.fill(height)(ListBuffer.fill(width)(' '))
    while (i < height) { //给游戏界面,画上边界
      //左右侧
      CharList(i)(0) = '*'
      CharList(i)(99)= '*'
      i+=1
    }
    while (j < width) {
      //上下侧
      CharList(0)(j) = '*'
      CharList(29)(j) = '*'
      j+=1
    }
    for (e <- o.obstructList) { //画障碍物  obstructList[][0:“x”,1:"y",2:"speedX",3:"speedY",4:"weight",5:"height"]
      i = e(1)
      j = e(0)
      while (i < e(1) + e(5) && i < height) {
        j = e(0)
        while (j < e(0) + e(4) && j < width) {
          CharList(i)(j)='|'
          j += 1
        }
        i += 1
      }
    }
    for (e <- m.moneyList) { //画金币  moneyList[][0:“x”,1:"y",2:"speedX",3:"speedY",4:"weight",5:"height"]
      if(e(0)<100 && e(1)<30){
        CharList(e(1))(e(0))='$'
      }
    }
    i = p.locationY
    j = p.locationX
    while (i < p.locationY + p.height && i < height) { //画人
      j = p.locationX
      while (j < p.locationX + p.width && j < width) {
        CharList(i)(j) = 'P'
        j += 1
      }
      i += 1
    }
    i=0
    while (i < height) {
      j=0
      while (j < width){
        printf("%c",CharList(29-i)(j))
        j+=1
      }
      printf("\n")
      i+=1
    }
  }
}

class gameThread extends Thread {
  var p=new Person()
  var o=new obstruct()
  var m=new money()
  var bg=new background()
  var timecount:Float=0 //单位:s
  var gamemode=1 //游戏开始
  override def run() {
    while(gamemode==1) {
      timecount=(timecount+0.5).toFloat
      bg.draw(o,p,m)//绘画ui界面
      println("计时: "+timecount+"s")
      p.score +=500  //每0.5秒500分
      p.score +=p.crashMoney(m)
      println("得分: "+p.score+" 分")
      p.commandP()
      p.move()
      o.appendObject()
      o.move()
      o.deleteObject()
      m.appendObject()
      m.move()
      m.deleteObject()
      gamemode=p.crashed(o)
      //Thread.sleep(500)
    }
  }
}
class account(){
  var currentName=""
  var account=ListBuffer[Map[String,String]](Map("用户名"->"root","密码"->"000","昵称"->"god","邮箱"->"8848@qq.com"))
  def register(){
    println("请输入你的用户名:")
    val username =StdIn.readLine()
    println("请输入你的密码")
    val password=StdIn.readLine()
    println("请输入你的昵称:")
    val nickname =StdIn.readLine()
    println("请输入你的邮箱")
    val email=StdIn.readLine()
    account.append(Map("用户名"->username,"密码"->password,"昵称"->nickname,"邮箱"->email))
    println("用户"+username+"注册成功!请重新登录")
  }
  def search(username:String,password:String) :Boolean ={
    for (e <- account){
      if (e.get("用户名").getOrElse("Null") == username && e.get("密码").getOrElse("Null") == password) {
        return true
      }
    }
    return false //登陆失败
  }
  def login(): Boolean ={
    println("请输入你的用户名:")
    val username =StdIn.readLine()
    currentName=username
    println("请输入你的密码")
    val password=StdIn.readLine()
    if(search(username,password)==false){
      println("密码错误,请重新登录")
      return false
    }
    else{
      println("欢迎 "+username+" 进入游戏!")
      return true
    }
  }
}
object game {
  def main(args:Array[String]):Unit = {
    val account = new account()
    var gamemode = 0 //游戏运行状态
    var loginmode = 1 //登录状态
    while (loginmode == 1) {
      println("------------------------------------------------\n" +
        "            欢迎来到天天酷跑            \n" +
        "            输入(1)进行登录            \n" +
        "            输入(2)进行注册            \n" +
        "            输入(#)退出游戏            \n" +
        "------------------------------------------------\n")
      StdIn.readLine() match {
        case "1" => {
          if (account.login()==false) {
            loginmode=1
            gamemode=0
          }
          else{
            println(account.currentName)
            loginmode=0  //跳出登录循环界面
            gamemode=1  //运行游戏
          }
        }
        case "2" => {
          account.register()
          loginmode=1
        }
        case "#" => {
          println("正在关闭天天酷跑...")
          return
        }
        case _ =>{
          println("输入非法,请检查后重新输入")
          loginmode=1
        }
      }
      if(gamemode == 1) {
        val Timigame=new gameThread()
        Timigame.start()
      }
    }
  }
}

效果图

登陆界面
游戏界面
游戏界面

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值