试图在克隆中让点离开Pacman

时间:2016-04-11 21:43:25

标签: c# distance pacman

最近,我一直致力于一个简单的吃豆人游戏,其中包括两个" Pacmen"随机产卵给他们吃。每当Pacman靠近石头时,我真的想尝试让石头离开它们,但我不确定这是怎么做的。有人可能会看看我的代码并给我一些建议吗?谢谢,我真的很感激!

Form1代码文件:

using System;
using System.Collections.Generic;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
using System.Threading;
using System.Runtime.InteropServices;
using System.Media;

namespace EaterGame1
{
public partial class Form1 : Form
{

    [DllImport("winmm.dll")]
    public static extern long PlaySound(String lpszName, long hModule, long dwFlags);

    private ArrayList Stones = new ArrayList(30);
    private Eater TheEater = new Eater(100, 100);
    private Eater TheOtherEater = new Eater(100, 50);
    private Random RandomGen = new Random();
    private const int NumberOfStones = 100;
    private Score TheScore = new Score(640, 350);
    private Score TheOtherScore = new Score(640, 330);
    private int TheSeconds = 0;
    private TimerDisplay TheTime = new TimerDisplay(7, 350);
    //private System.Windows.Forms.Timer timer1;
    //private System.ComponentModel.IContainer components;
    private Thread oThread = null; 




    public Form1()
    {
        InitializeComponent();

        InitializeStones();
        InitializeTimer();

        // reduce flicker

        SetStyle(ControlStyles.UserPaint, true);
        SetStyle(ControlStyles.AllPaintingInWmPaint, true);
        SetStyle(ControlStyles.DoubleBuffer, true);
    }


    private string m_strCurrentSoundFile = "miss.wav";
    public void PlayASound()
    {
        if (m_strCurrentSoundFile.Length > 0)
        {
            //PlaySound(Application.StartupPath + "\\" + m_strCurrentSoundFile, 0, 0);

            SoundPlayer simpleSound = new SoundPlayer(Application.StartupPath + "\\" + m_strCurrentSoundFile);
            simpleSound.Play();


        }
        m_strCurrentSoundFile = "";
        oThread.Abort();
    }

    public void PlaySoundInThread(string wavefile)
    {
        m_strCurrentSoundFile = wavefile;
        oThread = new Thread(new ThreadStart(PlayASound));
        oThread.Start();
    }


    public void InitializeTimer()
    {
        timer1.Start();
    }

    public void InitializeStones()
    {
        for (int i = 0; i < NumberOfStones; i++)
        {
            Stones.Add(new Stone(RandomGen.Next(
                10, ClientRectangle.Right - 10),
                RandomGen.Next(10, ClientRectangle.Bottom - 30)));

        }
    } 




    private void Form1_KeyDown(object sender, KeyEventArgs e)
    {


        string result = e.KeyData.ToString();
        Invalidate(TheEater.GetFrame());
        Invalidate(TheOtherEater.GetFrame());
        switch (result)
        {
            case "Left":
                TheEater.MoveLeft(ClientRectangle);
                Invalidate(TheEater.GetFrame());
                break;
            case "Right":
                TheEater.MoveRight(ClientRectangle);
                Invalidate(TheEater.GetFrame());
                break;
            case "Up":
                TheEater.MoveUp(ClientRectangle);
                Invalidate(TheEater.GetFrame());
                break;
            case "Down":
                TheEater.MoveDown(ClientRectangle);
                Invalidate(TheEater.GetFrame());
                break;
            case "E":
                TheOtherEater.MoveNorthWest(ClientRectangle);
                Invalidate(TheOtherEater.GetFrame());
                break;
            case "Q":
                TheOtherEater.MoveNorthEast(ClientRectangle);
                Invalidate(TheOtherEater.GetFrame());
                break;
            case "C":
                TheOtherEater.MoveSouthWest(ClientRectangle);
                Invalidate(TheOtherEater.GetFrame());
                break;
            case "Z":
                TheOtherEater.MoveSouthEast(ClientRectangle);
                Invalidate(TheOtherEater.GetFrame());
                break;
            case "W":
                TheOtherEater.MoveUp(ClientRectangle);
                Invalidate(TheOtherEater.GetFrame());
                break;
            case "A":
                TheOtherEater.MoveLeft(ClientRectangle);
                Invalidate(TheOtherEater.GetFrame());
                break;
            case "D":
                TheOtherEater.MoveRight(ClientRectangle);
                Invalidate(TheOtherEater.GetFrame());
                break;
            case "X":
                TheOtherEater.MoveDown(ClientRectangle);
                Invalidate(TheOtherEater.GetFrame());
                break;
            default:
                break;

        }

        int hit = CheckIntersection();
        if (hit != -1)
        {
            TheScore.Increment();
            PlaySoundInThread("hit.wav");
            Invalidate(TheScore.GetFrame());
            Invalidate(((Stone)Stones[hit]).GetFrame());
            Stones.RemoveAt(hit);
            if (Stones.Count == 0)
            {
                MessageBox.Show("You Win!\nYour time is " + TheTime.TheString + " seconds.\nThe first eater ate " + TheScore + " stones!\nThe second eater ate " + TheOtherScore + " stones!");
                Application.Exit();
            }
        }
        int hit2 = CheckIntersection2();
        if(hit2 != -1)
        {
            TheOtherScore.Increment();
            PlaySoundInThread("hit.wav");
            Invalidate(TheOtherScore.GetFrame());
            Invalidate(((Stone)Stones[hit2]).GetFrame());
            Stones.RemoveAt(hit2);
            if (Stones.Count == 0)
            {
                MessageBox.Show("You Win!\nYour time is " + TheTime.TheString + " seconds.\nThe first eater ate " + TheScore + " stones!\nThe second eater ate " + TheOtherScore + " stones!");
                Application.Exit();
            }
        }
    }

    private void Form1_Paint(object sender, PaintEventArgs e)
    {

        Graphics g = e.Graphics;
        g.FillRectangle(Brushes.White, 0, 0, this.ClientRectangle.Width, ClientRectangle.Height);


        // draw the score

        TheScore.Draw(g);
        TheOtherScore.Draw(g);

        // draw the time

        TheTime.Draw(g, TheSeconds);


        // draw the stones

        for (int i = 0; i < Stones.Count; i++)
        {
            ((Stone)Stones[i]).Draw(g);
        }

        // also draw the eater
        TheEater.Draw(g);
        TheOtherEater.Draw(g);


    }


    private int CheckIntersection()
    {
        for (int i = 0; i < Stones.Count; i++)
        {
            Rectangle stoneRect = ((Stone)Stones[i]).GetFrame();
            if (TheEater.GetFrame().IntersectsWith(stoneRect))
            {
                return i;
            }
        }

        return -1;
    }

    private int CheckIntersection2()
    {
        for (int i = 0; i < Stones.Count; i++)
        {
            Rectangle stoneRect = ((Stone)Stones[i]).GetFrame();
            if (TheOtherEater.GetFrame().IntersectsWith(stoneRect))
            {
                return i;
            }
        }

        return -1;
    }


    private void timer1_Tick(object sender, EventArgs e)
    {

        TheSeconds++;
        Invalidate(TheTime.GetFrame());

    }

    private void Form1_Load(object sender, EventArgs e)
    {

    }
}

}

食者代码文件:

using System;
using System.Drawing;
using System.Drawing.Imaging;

namespace EaterGame1
{
/// <summary>
/// Eats all the dots
/// </summary>
public class Eater
{
    public Point Position;
    static Bitmap EaterImage = null;
    static Bitmap EaterImage2 = null;
    static Bitmap EaterImage3 = null;
    static Bitmap EaterImage4 = null;
    int inc = 3;
    int LastPositionX = 0;
    int LastPositionY = 0;

    public Eater()
    {
        // 
        // TODO: Add constructor logic here
        //
        Position.X = 30;
        Position.Y = 35;
        if (EaterImage == null)
        {
            EaterImage = new Bitmap("eater.gif");
        }

        if (EaterImage2 == null)
        {
            EaterImage2 = new Bitmap("eater2.gif");
        }

        if(EaterImage3 == null)
        {
            EaterImage3 = new Bitmap("eater3.gif");
        }

        if (EaterImage4 == null)
        {
            EaterImage4 = new Bitmap("eater4.gif");
        }
    }

    public Eater(int x, int y)
    {
        // 
        // TODO: Add constructor logic here
        //
        Position.X = x;
        Position.Y = y;
        if (EaterImage == null)
        {
            EaterImage = new Bitmap("eater.gif");
        }

        if (EaterImage2 == null)
        {
            EaterImage2 = new Bitmap("eater2.gif");
        }

        if (EaterImage3 == null)
        {
            EaterImage3 = new Bitmap("eater3.gif");
        }

        if (EaterImage4 == null)
        {
            EaterImage4 = new Bitmap("eater4.gif");
        }

    }

    public Rectangle GetFrame()
    {
        Rectangle myRect = new Rectangle(Position.X, Position.Y, EaterImage.Width, EaterImage.Height);
        return myRect;
    }

    public void Draw(Graphics g)
    {

        Rectangle destR = new Rectangle(Position.X, Position.Y, EaterImage.Width, EaterImage.Height);
        Rectangle srcR = new Rectangle(0, 0, EaterImage.Width, EaterImage.Height);

        // make it look like the mouth is moving
        if (((Position.X % 2 == 1) && ((Position.X - LastPositionX) != 0)) ||
             ((Position.Y % 2 == 1) && ((Position.Y - LastPositionY) != 0))
           )
            g.DrawImage(EaterImage, destR, srcR, GraphicsUnit.Pixel);
        else
            g.DrawImage(EaterImage2, destR, srcR, GraphicsUnit.Pixel);
        if (((Position.X % 2 == 1) && ((Position.X - LastPositionX) != 0)) ||
         ((Position.Y % 2 == 1) && ((Position.Y - LastPositionY) != 0))
       )
            g.DrawImage(EaterImage3, destR, srcR, GraphicsUnit.Pixel);
        else
            g.DrawImage(EaterImage4, destR, srcR, GraphicsUnit.Pixel);

        LastPositionX = Position.X;
        LastPositionY = Position.Y;

    }

    public void MoveLeft(Rectangle r)
    {
        if (Position.X <= 0)
            return;  // precondition

        Position.X -= inc;
    }

    public void MoveRight(Rectangle r)
    {
        if (Position.X >= r.Width - EaterImage.Width)
            return;  // precondition

        Position.X += inc;
    }

    public void MoveUp(Rectangle r)
    {
        if (Position.Y <= 0)
            return;  // precondition

        Position.Y -= inc;
    }

    public void MoveDown(Rectangle r)
    {
        if (Position.Y >= r.Height - EaterImage.Height)
            return;  // precondition

        Position.Y += inc;
    }

    public void MoveNorthWest(Rectangle r)
    {
        MoveUp(r);
        MoveRight(r);
    }

    public void MoveNorthEast(Rectangle r)
    {
        MoveUp(r);
        MoveLeft(r);
    }

    public void MoveSouthWest(Rectangle r)
    {
        MoveDown(r);
        MoveRight(r);
    }

    public void MoveSouthEast(Rectangle r)
    {
        MoveDown(r);
        MoveLeft(r);
    }
}

}

石头代码文件:

using System;
using System.Drawing;
using System.Drawing.Imaging;

namespace EaterGame1
{
/// <summary>
/// Summary description for Stone.
/// </summary>
public class Stone
{
    public Point Position;
    static Bitmap StoneImage = null;

    public Stone()
    {
        //
        // TODO: Add constructor logic here
        //
        Position.X = 0;
        Position.Y = 0;
        if (StoneImage == null)
        {
            StoneImage = new Bitmap("stone.gif");
        }
    }

    public Stone(int x, int y)
    {
        //
        // TODO: Add constructor logic here
        //
        Position.X = x;
        Position.Y = y;
        if (StoneImage == null)
        {
            StoneImage = new Bitmap("stone.gif");
        }
    }

    public Rectangle GetFrame()
    {
        Rectangle myRect = new Rectangle(Position.X, Position.Y, StoneImage.Width, StoneImage.Height);
        return myRect;
    }

    public void Draw(Graphics g)
    {
        Rectangle destR = new Rectangle(Position.X, Position.Y, StoneImage.Width, StoneImage.Height);
        Rectangle srcR = new Rectangle(0, 0, StoneImage.Width, StoneImage.Height);
        g.DrawImage(StoneImage, destR, srcR, GraphicsUnit.Pixel);
    }
}
}

2 个答案:

答案 0 :(得分:0)

我会给石头一个方法(一帧一次调用)到效果:

public void Move(Point eater){
    xDif = Position.x - eater.x;
    if(xDif != 0) Position.x += inc*(xDif)/abs(xDif);
    //you will need similar code to address the y
}

其中inc是你希望石头移动的速度。该算法适用于移动开放空间和封闭空间。您仍然需要使用代码来防止石头进入墙壁,但感觉我没有看到您用于墙壁的任何代码,我无法帮助您。

答案 1 :(得分:0)

我会创建一个新方法并将其放在program.cs中的switch语句中。

我的代码并不完美,但我希望这可以解决这个问题。

switch (result)
        {
            case "Left":
                TheEater.MoveLeft(ClientRectangle);
                Invalidate(TheEater.GetFrame());
                CheckIfEaterIsCloseToMe(); // new method
                break;
            case "Right":
                TheEater.MoveRight(ClientRectangle);
                Invalidate(TheEater.GetFrame());
                break;

...

private void CheckIfEaterIsCloseToMe()
{
    for (int i = 0; i < Stones.Count; i++)
    {
        Rectangle stoneRect = ((Stone)Stones[i]).GetFrame();
        if (TheOtherEater.GetFrame().IsClose(stoneRect, TheOtherEater.GetFrame()))
        {
            // call move method maybe - or just move
        }
    }


}

private bool IsClose(Rectange r1, Rectangle r2)
{
    // check if the r1 is close to r2 -- get the left - right - top - bottom of each rectangle
    // first you need to determine if the other rectangle is on the left or right or top or bottom of this rectangle
    if( ( (r1.X + r1.Width)  - r2.X) <= 20 ) // 20 is threshold -- if on the right -- take the right side minus left side
    {
           // move stone how you want -> maybe to the right more
           return true;
    }

    return false;
}