2010/07/31 13:54




XNA 4.0 Beta 로 만들어본 총알 피하기 게임입니다.
Zip압축과 패키지인 ccgame을 같이 올립니다.
게임을 실행하기 위해서는 XNA Redistribuatble이 필요할텐데..
베타버전이라 그런지 4.0 버젼이 없다는게;;
어찌됐건 .Net Framework도 필요하고.. 에.. 또 그리고;;
(왠지 무책임ㅋ;;)

이것저것 참고하며 만들었지만 워낙 초보라 소스는 허접함의 극치네요.
그래도 일단은.. 작동하긴 합니다 ㅎㅎ
창피하긴 하지만 주석도 달아서 소스 공개합니다~ ^^

using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;

namespace Dodge
{
    public class Game1 : Microsoft.Xna.Framework.Game
    {
        GraphicsDeviceManager graphics;
        SpriteBatch spriteBatch;

        Texture2D backgroundTexture; // 배경
        Texture2D playerTexture; // 플레이어
        Texture2D enemyTexture; // 적
        Rectangle viewportRect; // 화면 해상도
        Vector2 playerPos; // 플레이어 위치
        Vector2 tumbStickPos; // 게임패드의 스틱 위치

        Vector2[] enemyPos; // 적 위치 배열
        double[] enemyAng; // 적 생성시 플레이어와의 각도 배열
        bool[] enemyFire; // 적의 현재 발사상태 배열
        float enemySpeed = 1.0f; // 적의 속도
        int enemyCount = 1; // 적의 현재 갯수
        int maxenemy = 200; // 적의 최대 갯수

        Rectangle playerRect; // 충돌체크를 위한 플레이어 Rectangle
        Rectangle[] enemyRect; // 충돌체크를 위한 각 적의 Rectangle 배열

        SpriteFont font; // 스프라이트 폰트
        int Timer = 0; // 새게임 시작시 전체플레이 시간중 게임이 시작된 시간을 빼기 위한 타이머

        Random rnd = new Random();

        // 게임 모드 분할
        enum GameMode
        {
            Intro,
            Game,
            GameOver,
        };
        GameMode gameMode = GameMode.Intro; //  시작시 Intro로 실행되기 위해 미리 초기화

        public Game1()
        {
            graphics = new GraphicsDeviceManager(this);
            Content.RootDirectory = "Content";
        }

        protected override void Initialize()
        {
            graphics.PreferredBackBufferWidth = 800; // 해상도 가로사이즈
            graphics.PreferredBackBufferHeight = 600; // 해상도 새로사이즈
            graphics.IsFullScreen = false; // 전체화면을 사용 안함
            graphics.ApplyChanges(); // 변경된 내용 적용

            // 최대 적수로 배열 할당
            enemyPos = new Vector2[maxenemy];
            enemyAng = new double[maxenemy];
            enemyRect = new Rectangle[maxenemy];
            enemyFire = new bool[maxenemy];

            base.Initialize();
        }

        protected override void LoadContent()
        {
            spriteBatch = new SpriteBatch(GraphicsDevice);

            // 각 스프라이트 및 스프라이트 폰트 등록
            backgroundTexture = Content.Load("background");
            playerTexture = Content.Load("player");
            enemyTexture = Content.Load("enemy");
            font = Content.Load("SpriteFont");

            // 화면 해상도 입력
            viewportRect = new Rectangle(0, 0,
                graphics.GraphicsDevice.Viewport.Width,
                graphics.GraphicsDevice.Viewport.Height);

            // 플레이어 위치 가운데로 할당
            playerPos = new Vector2(
                graphics.GraphicsDevice.Viewport.Width / 2 - playerTexture.Width / 2,
                graphics.GraphicsDevice.Viewport.Height / 2 - playerTexture.Height / 2);
        }

        protected override void UnloadContent()
        {
        }

        protected override void Update(GameTime gameTime)
        {
            KeyboardState keyboardState = Keyboard.GetState();
            
            // ESC나 Back버튼이 눌릴경우 게임 아웃
            if (keyboardState.IsKeyDown(Keys.Escape) ||
                GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
                this.Exit();
            
            // Intro 모드탕
            if (gameMode == GameMode.Intro)
            {
                // Enter키, Start버튼 입력시
                if (keyboardState.IsKeyDown(Keys.Enter) ||
                    GamePad.GetState(PlayerIndex.One).Buttons.Start == ButtonState.Pressed)
                {
                    gameMode = GameMode.Game; // 게임모드 Game으로 변경
                }
            }
            
            // GameOver 모드
            else if (gameMode == GameMode.GameOver)
            {
                // Enter키, Start버튼 입력시
                if (keyboardState.IsKeyDown(Keys.Enter) ||
                    GamePad.GetState(PlayerIndex.One).Buttons.Start == ButtonState.Pressed)
                {
                    // 플레이어 위치 가운데로 초기화
                    playerPos = new Vector2(
                        graphics.GraphicsDevice.Viewport.Width / 2 - playerTexture.Width / 2,
                        graphics.GraphicsDevice.Viewport.Height / 2 - playerTexture.Height / 2);

                    // 적의 발사상태 초기화
                    for (int i = 0; i < enemyCount && i < maxenemy; i++)
                    {
                        enemyFire[i] = false;
                    }

                    Timer = 0; // 타이머 초기화
                    enemyCount = 1; // 적 카운터 초기화
                    enemySpeed = 1.0f; // 적 스피드 초기화
                    gameMode = GameMode.Game; // 게임모드 Game으로 변경
                }
            }

            // Game 모드
            else if (gameMode == GameMode.Game)
            {
                // 타이머가 0이면
                if (Timer == 0)
                {
                    // 게임 시작시의 현재까지의 TotalSeconds를 받아와서 Timer변수에 입력
                    Timer = (int)gameTime.TotalGameTime.TotalSeconds;
                }

                // 게임패드의 스틱 움직임 수치 입력
                tumbStickPos.X = GamePad.GetState(PlayerIndex.One).ThumbSticks.Left.X;
                tumbStickPos.Y = GamePad.GetState(PlayerIndex.One).ThumbSticks.Left.Y;

                // 게임패드 입력에 따라 플레이어 기체를 움직인다.
                if (GamePad.GetState(PlayerIndex.One).ThumbSticks.Left.X < 0)
                {
                    playerPos.X += tumbStickPos.X * 4.0f;
                }
                if (GamePad.GetState(PlayerIndex.One).ThumbSticks.Left.X > 0)
                {
                    playerPos.X += tumbStickPos.X * 4.0f;
                }
                if (GamePad.GetState(PlayerIndex.One).ThumbSticks.Left.Y > 0)
                {
                    playerPos.Y -= tumbStickPos.Y * 4.0f;
                }
                if (GamePad.GetState(PlayerIndex.One).ThumbSticks.Left.Y < 0)
                {
                    playerPos.Y -= tumbStickPos.Y * 4.0f;
                }

                // 키보드 입력에 따라 플레이어 기체를 움직인다.
                if (keyboardState.IsKeyDown(Keys.Left))
                {
                    playerPos.X -= 3.0f;
                }
                if (keyboardState.IsKeyDown(Keys.Right))
                {
                    playerPos.X += 3.0f;
                }
                if (keyboardState.IsKeyDown(Keys.Up))
                {
                    playerPos.Y -= 3.0f;
                }
                if (keyboardState.IsKeyDown(Keys.Down))
                {
                    playerPos.Y += 3.0f;
                }

                // 플레이어기체가 화면밖으로 나가는 것을 방지
                if (playerPos.X < 0)
                {
                    playerPos.X = 0;
                }
                if (playerPos.X > graphics.GraphicsDevice.Viewport.Width - playerTexture.Width)
                {
                    playerPos.X = graphics.GraphicsDevice.Viewport.Width - playerTexture.Width;
                }
                if (playerPos.Y < 0)
                {
                    playerPos.Y = 0;
                }
                if (playerPos.Y > graphics.GraphicsDevice.Viewport.Height - playerTexture.Height)
                {
                    playerPos.Y = graphics.GraphicsDevice.Viewport.Height - playerTexture.Height;
                }

                // 충돌체크를 위한 플레이어의 Rectangle을 만듬 (1/2크기)
                playerRect = new Rectangle(
                    (int)playerPos.X + (playerTexture.Width / 4 * 1),
                    (int)playerPos.Y + (playerTexture.Height / 4 * 1),
                    playerTexture.Width / 4 * 3, playerTexture.Height / 4 * 3);

                // 적의 생성 및 충돌 체크를 위한 For 문, 최대적수를 넘지 않고 현재 적의 수 많큼 돌린다. 
                for (int i = 0; i < enemyCount && i < maxenemy; i++)
                {
                    //  적이 발사 되지 않았다면
                    if (enemyFire[i] == false)
                    {
                        // 화면 밖에 적을 생성한다. 랜덤함수로 상,하,좌,우 별로 포지션 할당
                        int x = rnd.Next(1, 4);
                        int pos_x = new int();
                        int pos_y = new int();
                        if (x == 1)
                        {
                            pos_x = rnd.Next(0, 800);
                            pos_y = rnd.Next(-10, 0);
                        }
                        if (x == 2)
                        {
                            pos_x = rnd.Next(800, 810);
                            pos_y = rnd.Next(0, 600);
                        }
                        if (x == 3)
                        {
                            pos_x = rnd.Next(0, 800);
                            pos_y = rnd.Next(600, 610);
                        }
                        if (x == 4)
                        {
                            pos_x = rnd.Next(-10, 0);
                            pos_y = rnd.Next(0, 600);
                        }

                        // 램덤함수로 생성된 포지션을 적에게 할당
                        enemyPos[i] = new Vector2(pos_x, pos_y);

                        // 플레이어 위치와 적의 위치로 각도를 구함
                        enemyAng[i] = Math.Atan2(playerPos.Y - enemyPos[i].Y,
                            playerPos.X - enemyPos[i].X);
                        enemyFire[i] = true; // 적의 상태를 발사로 바꿈
                    }
                    
                    // 입력된 각도를 토대로 적의 위치를 계속 수정한다.
                    enemyPos[i].X += (float)Math.Cos(enemyAng[i]) * enemySpeed;
                    enemyPos[i].Y += (float)Math.Sin(enemyAng[i]) * enemySpeed;

                    // 적의 위치가 화면 밖을 넘어가면
                    if (enemyPos[i].X < -100 || enemyPos[i].X > 900 ||
                        enemyPos[i].Y < -100 || enemyPos[i].Y > 700)
                    {
                        enemyFire[i] = false; // 적의 발사 상태를 False로 바꿈.
                    }

                    // 충돌체크를 위한 적기의 Rectangle을 만든 (1/2크기)
                    enemyRect[i] = new Rectangle(
                        (int)enemyPos[i].X + (enemyTexture.Width / 4 * 1),
                        (int)enemyPos[i].Y + (enemyTexture.Height / 4 * 1),
                        enemyTexture.Width / 4 * 3,
                        enemyTexture.Height / 4 * 3);

                    // 플레이어와 적의 충돌을 체크한다.
                    if (playerRect.Intersects(enemyRect[i]))
                    {
                        gameMode = GameMode.GameOver; // 충돌시 게임모드 GameOver로 바꿈.
                        break;
                    }
                }

                enemySpeed += 0.001f; // 적의 속도를 올려준다.
                
                // 매초마다 적의 수 증가 (총 게임 실행시간 - Game모드 타이머)
                enemyCount = (int)gameTime.TotalGameTime.TotalSeconds - Timer;
            }

            base.Update(gameTime);
        }

        protected override void Draw(GameTime gameTime)
        {
            GraphicsDevice.Clear(Color.CornflowerBlue);

            spriteBatch.Begin();

            spriteBatch.Draw(backgroundTexture, viewportRect, Color.White); // 배경 그림
            spriteBatch.Draw(playerTexture, playerPos, Color.White); // 플레이어 그림

            // 게임모드 Intro
            if (gameMode == GameMode.Intro)
            {
                // 게임 시작 안내문구
                spriteBatch.DrawString(font, "Press Start Button to Play Game",
                    new Vector2(260, 500), Color.Yellow);
            }
            
            // 게임모드 GameOver
            else if (gameMode == GameMode.GameOver)
            {
                // 적을 위치를 표시하기 위한 For문
                for (int i = 0; i < enemyCount && i < maxenemy; i++)
                {
                    spriteBatch.Draw(enemyTexture, enemyPos[i], Color.White);
                }
                // 몇초간 플레이 했는지 화면에 표시
                spriteBatch.DrawString(font, " You Survived for " + enemyCount + " Seconds",
                    new Vector2(260, 250), Color.Yellow);
                // 게임 다시 시작을 위한 안내문구 표시
                spriteBatch.DrawString(font, "Press Start Button to Play Again",
                    new Vector2(260, 500), Color.Yellow);
            }

            // 게임모드 Game
            else if (gameMode == GameMode.Game)
            {
                // 적의 위치를 갱신한다.
                for (int i = 0; i < enemyCount && i < maxenemy; i++)
                {
                    spriteBatch.Draw(enemyTexture, enemyPos[i], Color.White);
                }
            }

            spriteBatch.End();

            base.Draw(gameTime);
        }
    }
}
Posted by 미노우
2010/06/12 14:33
헤더값만 받아와서 이미지가 맞는지 체크 후 이미지가 맞으면
Body부분, 원격지 이미지를 받아오는 함수입니다.
function get_image($url) {
	$ch = curl_init();
	curl_setopt($ch, CURLOPT_URL, $url);
	curl_setopt($ch, CURLOPT_TIMEOUT, 10);
	curl_setopt($ch, CURLOPT_HEADER, false); // 헤더를 받지 않는다.
	curl_setopt($ch, CURLOPT_NOBODY, true); // 바디를 받지 않는다.
	curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); // 결과값을 받는다
	curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); // 위치헤더가 있으면 따라간다
	curl_setopt($ch, CURLOPT_AUTOREFERER, true); // 리디렉션시 자동으로 리퍼러 설정
	curl_setopt($ch, CURLOPT_REFERER, $url);
	curl_setopt($ch, CURLOPT_USERAGENT, "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0)");

	curl_exec($ch); // URL 내용을 가져온다
	$info = curl_getinfo($ch); // 상태 정보 받기

	// 200 코드와 content type이 image일 경우 Body가 포함된 결과값을 다시 받아와 출력한다
	if ($info['http_code'] == 200 && substr($info['content_type'],0,5) == "image") {
			curl_setopt($ch, CURLOPT_NOBODY, false); // 바디를 받는다로 속성 변경
			$buffer = curl_exec($ch); // URL 내용을 가져온다
			return $buffer; // 결과값 출력
	} else {
		return false;
	}

	curl_close($ch);
}
Posted by 미노우
2010/06/11 22:54


Rhino 3D & V-Ray & PhotoShop CS4
2010.06.11
Posted by 미노우