[Gtk-sharp-list] Keyboard problem in a Snake game

vronskij vronskij at gmail.com
Wed Jan 21 16:43:53 EST 2009


Hi, I have created a simple snake game in GTK C#. Everything works, except
for
the keyboard control. 

I have tried everything I have come to.
I did the  [GLib.ConnectBefore], I have overridden the default handler, I
have experimented 
with the focus. Nothing worked for me.

http://www.nabble.com/file/p21592773/head.png head.png 
http://www.nabble.com/file/p21592773/apple.png apple.png 
http://www.nabble.com/file/p21592773/dot.png dot.png 

This is interesting. I have done it in other toolkits even javagnome, but
here I am perfectly lost.

thanks for any suggestions.

PS: this is for my upcoming new GTK# tutorial

jan bodnar

// snake.cs
------------------------------------


using Gtk;
using System;
 
class Snake : Window {
 

    public Snake() : base("Snake")
    {
        SetDefaultSize(300, 270);
        SetPosition(WindowPosition.Center);


        DeleteEvent += delegate { Application.Quit(); };
        
        Add(new Board());

        ShowAll();
    }

    public static void Main()
    {
        Application.Init();
        new Snake();
        Application.Run();
    }
}


// board.cs
--------------------------------------
using System;
using Gtk;
using Cairo;


public class Board : DrawingArea {

    private const int WIDTH = 300;
    private const int HEIGHT = 300;
    private const int DOT_SIZE = 10;
    private const int ALL_DOTS = 900;
    private const int RAND_POS = 29;

    private int[] x = new int[ALL_DOTS];
    private int[] y = new int[ALL_DOTS];

    private int dots;
    private int apple_x;
    private int apple_y;

    private bool left = false;
    private bool right = true;
    private bool up = false;
    private bool down = false;
    private bool inGame = true;

    private ImageSurface dot;
    private ImageSurface apple;
    private ImageSurface head;


    public Board() {

        //BackColor = Color.Black;
        //DoubleBuffered = true;
        ModifyFg(StateType.Normal, new Gdk.Color(0, 0, 0));
        SetSizeRequest(320, 310); 
        KeyReleaseEvent += OnKeyUp;
        
        DeleteEvent += delegate { Application.Quit(); };
        

        Show();

        //GrabFocus();

        ExposeEvent += OnExpose;

        try {
            dot = new ImageSurface("dot.png");
            head = new ImageSurface("head.png");
            apple = new ImageSurface("apple.png");
        } catch {
            Console.WriteLine("Images not found");
            Environment.Exit(1);
        }

        initGame();
    }


    bool OnTimer()
    {

        if (inGame) {
            
            checkApple();
            checkCollision();
            move();
            QueueDraw();
            
            return true;
        } else {
            return false;   
        }
    }


    private void initGame() {

        dots = 3;

        for (int z = 0; z < dots; z++) {
            x[z] = 50 - z * 10;
            y[z] = 50;
        }

        locateApple();
        //KeyUp += new KeyEventHandler(OnKeyUp);
        //KeyPressEvent += OnKeyUp;

        GLib.Timeout.Add(100, new GLib.TimeoutHandler(OnTimer));

        ExposeEvent += OnExpose;

    }


    void OnExpose(object sender, ExposeEventArgs e) {

        DrawingArea area = (DrawingArea) sender;
        Cairo.Context cr =  Gdk.CairoHelper.Create(area.GdkWindow);


        if (inGame) {
            
            cr.SetSourceRGB(0, 0, 0);
            cr.Paint();

            cr.SetSourceSurface(apple, apple_x, apple_y);
            cr.Paint();

            for (int z = 0; z < dots; z++) {
                if (z == 0) {
                    cr.SetSourceSurface(head, x[z], y[z]);
                    cr.Paint();
                } else {
                    cr.SetSourceSurface(dot, x[z], y[z]);                    
                    cr.Paint();
                }
            }
            
            ((IDisposable) cr.Target).Dispose();
            ((IDisposable) cr).Dispose();

        } else {
            gameOver(cr);
        }
    }


    void gameOver(Cairo.Context cr) {

        string message = "Game Over";
        //StringFormat format = new StringFormat();
        //format.Alignment = StringAlignment.Center;
        //format.LineAlignment = StringAlignment.Center;
        
        //g.DrawString(msg, Font, Brushes.White, ClientRectangle, format);
        //cr.ShowText();
        int x = Allocation.Width / 2;
        int y = Allocation.Height / 2;

        
        TextExtents extents = cr.TextExtents(message);

        cr.MoveTo(x - extents.Width/2, y);
        cr.TextPath(message);
        cr.Clip();
        cr.Stroke();
        inGame = false;

    }


    void checkApple() {

        if ((x[0] == apple_x) && (y[0] == apple_y)) {
            dots++;
            locateApple();
        }
    }

    void move() {

        for (int z = dots; z > 0; z--) {
            x[z] = x[(z - 1)];
            y[z] = y[(z - 1)];
        }

        if (left) {
            x[0] -= DOT_SIZE;
        }

        if (right) {
            x[0] += DOT_SIZE;
        }

        if (up) {
            y[0] -= DOT_SIZE;
        }

        if (down) {
            y[0] += DOT_SIZE;
        }
    }

    void checkCollision() {

        for (int z = dots; z > 0; z--) {
            if ((z > 4) && (x[0] == x[z]) && (y[0] == y[z])) {
                inGame = false;
            }
        }

        if (y[0] > HEIGHT) {
            inGame = false;
        }

        if (y[0] < 0) {
            inGame = false;
        }

        if (x[0] > WIDTH) {
            inGame = false;
        }

        if (x[0] < 0) {
            inGame = false;
        }
    }

    void locateApple() {
        Random rand = new Random();
        int r = (int) (rand.Next(RAND_POS));
        apple_x = ((r * DOT_SIZE));
        r = (int) (rand.Next(RAND_POS));
        apple_y = ((r * DOT_SIZE));
    }
    
    //protected override bool OnKeyReleaseEvent(Gdk.EventKey e)
    
    [GLib.ConnectBefore]
    void OnKeyUp(object sender, KeyReleaseEventArgs args)
    {
        //int key = (int) e.KeyValue;
        //base.OnKeyPressEvent(e);
        Console.WriteLine("key");
        
        //Gdk.Key key = e.Key;
        
        Gdk.Key key = args.Event.Key;

        if ((key == Gdk.Key.Left) && (!right)) {
            left = true;
            up = false;
            down = false;
        }

        if ((key == Gdk.Key.Right) && (!left)) {
            right = true;
            up = false;
            down = false;
        }

        if ((key == Gdk.Key.Up) && (!down)) {
            up = true;
            right = false;
            left = false;
        }

        if ((key == Gdk.Key.Down) && (!up)) {
            down = true;
            right = false;
            left = false;
        }
        //return true;
    }
}





-- 
View this message in context: http://www.nabble.com/Keyboard-problem-in-a-Snake-game-tp21592773p21592773.html
Sent from the Mono - Gtk# mailing list archive at Nabble.com.



More information about the Gtk-sharp-list mailing list