Merge branch 'master' of manuel-voegele.de:inf3

This commit is contained in:
Wafa Sadri
2014-05-08 10:33:45 +02:00
10 changed files with 173 additions and 73 deletions

View File

@@ -9,27 +9,28 @@
<OutputType>Exe</OutputType> <OutputType>Exe</OutputType>
<RootNamespace>inf3</RootNamespace> <RootNamespace>inf3</RootNamespace>
<AssemblyName>inf3</AssemblyName> <AssemblyName>inf3</AssemblyName>
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' "> <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
<DebugSymbols>true</DebugSymbols> <DebugSymbols>True</DebugSymbols>
<DebugType>full</DebugType> <DebugType>full</DebugType>
<Optimize>false</Optimize> <Optimize>False</Optimize>
<OutputPath>bin\Debug</OutputPath> <OutputPath>bin\Debug</OutputPath>
<DefineConstants>DEBUG;</DefineConstants> <DefineConstants>DEBUG;</DefineConstants>
<ErrorReport>prompt</ErrorReport> <ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel> <WarningLevel>4</WarningLevel>
<PlatformTarget>x86</PlatformTarget> <PlatformTarget>x86</PlatformTarget>
<ConsolePause>false</ConsolePause> <ConsolePause>False</ConsolePause>
<additionalargs>/unsafe</additionalargs> <additionalargs>/unsafe</additionalargs>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' "> <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
<DebugType>none</DebugType> <DebugType>none</DebugType>
<Optimize>true</Optimize> <Optimize>True</Optimize>
<OutputPath>bin\Release</OutputPath> <OutputPath>bin\Release</OutputPath>
<ErrorReport>prompt</ErrorReport> <ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel> <WarningLevel>4</WarningLevel>
<PlatformTarget>x86</PlatformTarget> <PlatformTarget>x86</PlatformTarget>
<ConsolePause>false</ConsolePause> <ConsolePause>False</ConsolePause>
</PropertyGroup> </PropertyGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" /> <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<ItemGroup> <ItemGroup>
@@ -74,6 +75,7 @@
<Compile Include="src\Gui\IChatMessage.cs" /> <Compile Include="src\Gui\IChatMessage.cs" />
<Compile Include="src\Gui\MapPanel.cs" /> <Compile Include="src\Gui\MapPanel.cs" />
<Compile Include="src\Pathfinder.cs" /> <Compile Include="src\Pathfinder.cs" />
<Compile Include="src\Gui\IEntity.cs" />
</ItemGroup> </ItemGroup>
<ItemGroup /> <ItemGroup />
<ItemGroup> <ItemGroup>

View File

@@ -1,6 +1,6 @@
using System.Net.Sockets; using System.Net.Sockets;
using System.Collections.Generic; using System.Collections.Generic;
using WorldOfPeacecraft; using System.Threading;
namespace WorldOfPeacecraft namespace WorldOfPeacecraft
{ {
@@ -16,6 +16,7 @@ namespace WorldOfPeacecraft
private Map Map; private Map Map;
private Buffer SenderBuffer; private Buffer SenderBuffer;
private IGui Gui; private IGui Gui;
private int SelfId;
public Backend (IGui gui) public Backend (IGui gui)
{ {
@@ -30,15 +31,21 @@ namespace WorldOfPeacecraft
Rec = new Receiver (Client, receiverBuffer); Rec = new Receiver (Client, receiverBuffer);
Send = new Sender (Client, SenderBuffer); Send = new Sender (Client, SenderBuffer);
SenderBuffer.AddLine ("get:map"); SenderBuffer.AddLine ("get:map");
SenderBuffer.AddLine ("get:me");
SenderBuffer.AddLine ("get:ents"); SenderBuffer.AddLine ("get:ents");
} }
public IEnumerable<IPositionable> GetDragons () public void SetSelfId (int id)
{
this.SelfId = id;
}
public IEnumerable<IEntity> GetDragons ()
{ {
return Dragons.Values; return Dragons.Values;
} }
public IEnumerable<IPositionable> GetPlayers () public IEnumerable<IEntity> GetPlayers ()
{ {
return Players.Values; return Players.Values;
} }
@@ -139,6 +146,26 @@ namespace WorldOfPeacecraft
SenderBuffer.AddLine("ask:mv:rgt"); SenderBuffer.AddLine("ask:mv:rgt");
} }
public void MoveTo (int x, int y)
{
if (Map.GetTiles () [x, y].IsWalkable ()) {
Thread thread = new Thread (() => WalkTo (x, y));
thread.IsBackground = true;
thread.Start ();
}
}
private void WalkTo (int x, int y)
{
LinkedList<Coordinate> path = Pathfinder.FindPath (Players [SelfId].Coord, new Coordinate (x, y), Map);
Pathwalker walker = new Pathwalker ();
walker.SetCoords (path);
while (walker.HasMoreSteps()) {
SenderBuffer.AddLine("ask:" + walker.NextStep());
Thread.Sleep(250);
}
}
public void RefreshGui() public void RefreshGui()
{ {
Gui.PerformRefresh(); Gui.PerformRefresh();
@@ -157,3 +184,4 @@ namespace WorldOfPeacecraft
} }
} }
} }

View File

@@ -6,7 +6,7 @@ using System.Threading.Tasks;
namespace WorldOfPeacecraft namespace WorldOfPeacecraft
{ {
public abstract class Entity : IPositionable public abstract class Entity : IEntity
{ {
public int Id; public int Id;
public Coordinate Coord; public Coordinate Coord;

View File

@@ -74,7 +74,6 @@ namespace WorldOfPeacecraft
ChatPanel.Location = new Point (MapPanel.Width, 0); ChatPanel.Location = new Point (MapPanel.Width, 0);
ChatPanel.Size = new Size (ChatWidth, MapPanel.Height); ChatPanel.Size = new Size (ChatWidth, MapPanel.Height);
this.ResumeLayout(); this.ResumeLayout();
this.PerformLayout();
ChatPanel.UpdateData (); ChatPanel.UpdateData ();
this.Refresh(); this.Refresh();
})); }));

View File

@@ -6,9 +6,9 @@ namespace WorldOfPeacecraft
{ {
ITile[,] GetMap(); ITile[,] GetMap();
IEnumerable<IPositionable> GetPlayers(); IEnumerable<IEntity> GetPlayers();
IEnumerable<IPositionable> GetDragons(); IEnumerable<IEntity> GetDragons();
IEnumerable<IChatMessage> GetChatMessages(); IEnumerable<IChatMessage> GetChatMessages();
@@ -17,10 +17,10 @@ namespace WorldOfPeacecraft
void SendCommand (string command); void SendCommand (string command);
void moveUp(); void moveUp();
void moveDown(); void moveDown();
void moveLeft(); void moveLeft();
void moveRight(); void moveRight();
void MoveTo(int x, int y);
void StartThreads(); void StartThreads();

7
src/Gui/IEntity.cs Normal file
View File

@@ -0,0 +1,7 @@
namespace WorldOfPeacecraft
{
public interface IEntity : IPositionable
{
int GetId();
}
}

View File

@@ -1,3 +1,4 @@
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Drawing; using System.Drawing;
using System.Windows.Forms; using System.Windows.Forms;
@@ -10,11 +11,31 @@ namespace WorldOfPeacecraft
private const int EntitySize = 10; private const int EntitySize = 10;
private IBackend Backend; private IBackend Backend;
private string ImagesFolder = "textures/";
private Image BowAndArrow;
private Image Dragon1;
private Image Dragon2;
private Image Dragon3;
private Image Forest;
private Image Knight;
private Image Walkable;
private Image Water;
private Dictionary<int, int> dragonImageMappings = new Dictionary<int, int>();
private Random random = new Random ();
public MapPanel (IBackend backend) public MapPanel (IBackend backend)
{ {
SetStyle (ControlStyles.OptimizedDoubleBuffer | ControlStyles.UserPaint | ControlStyles.AllPaintingInWmPaint, true);
Backend = backend; Backend = backend;
this.Paint += DoPaint;
this.PreviewKeyDown += board_KeyPress; this.PreviewKeyDown += board_KeyPress;
BowAndArrow = Image.FromFile (ImagesFolder + "bow-and-arrow.png", false);
Dragon1 = Image.FromFile (ImagesFolder + "dragon1.png");
Dragon2 = Image.FromFile (ImagesFolder + "dragon2.png");
Dragon3 = Image.FromFile (ImagesFolder + "dragon3.png");
Forest = Image.FromFile (ImagesFolder + "forest.png");
Knight = Image.FromFile (ImagesFolder + "knight.png");
Walkable = Image.FromFile (ImagesFolder + "walkable.jpg");
Water = Image.FromFile (ImagesFolder + "water.jpg");
} }
protected override void OnLayout (LayoutEventArgs levent) protected override void OnLayout (LayoutEventArgs levent)
@@ -50,18 +71,18 @@ namespace WorldOfPeacecraft
protected override void OnMouseClick (MouseEventArgs e) protected override void OnMouseClick (MouseEventArgs e)
{ {
base.OnMouseClick (e); base.OnMouseClick (e);
//TODO: Things. int targetX = e.X / TileSize;
int targetY = e.Y / TileSize;
Backend.MoveTo (targetX, targetY);
} }
public void DoPaint (object source, PaintEventArgs args) protected override void OnPaint (PaintEventArgs e)
{ {
BufferedGraphics buffer = BufferedGraphicsManager.Current.Allocate (this.CreateGraphics (), this.DisplayRectangle); Graphics g = e.Graphics;
Graphics g = buffer.Graphics;
lock (Backend) { lock (Backend) {
PaintMap (g); PaintMap (g);
PaintEntities (g); PaintEntities (g);
} }
buffer.Render();
} }
public void PaintMap (Graphics g) public void PaintMap (Graphics g)
@@ -70,7 +91,9 @@ namespace WorldOfPeacecraft
if (map != null) { if (map != null) {
for (int y = 0; y < map.GetLength(1); y++) { for (int y = 0; y < map.GetLength(1); y++) {
for (int x = 0; x < map.GetLength(0); x++) { for (int x = 0; x < map.GetLength(0); x++) {
PaintTile (g, map [x, y], x, y); int posx = x * TileSize;
int posy = y * TileSize;
PaintTile (g, map [x, y], posx, posy);
} }
} }
} }
@@ -81,44 +104,71 @@ namespace WorldOfPeacecraft
public void PaintTile (Graphics g, ITile tile, int x, int y) public void PaintTile (Graphics g, ITile tile, int x, int y)
{ {
int posx = x * TileSize; Image image = null;
int posy = y * TileSize; if (tile.IsWater ()) {
Color color; image = Water;
if (tile.IsHuntable ()) { }
color = Color.DarkGreen; else {
} // Stupid parenthesis image = Walkable;
else if (tile.IsForest ()) { }
color = Color.Green; if (image != null) {
} else if (tile.IsWater ()) { PaintImage (g, x, y, image);
color = Color.Blue; } else {
} else if (tile.IsWalkable ()) { g.FillRectangle(new SolidBrush(Color.Red), x, y, TileSize, TileSize);
color = Color.Yellow; }
} else if (tile.IsWall ()) { if (tile.IsWall ()) {
color = Color.DarkGray; g.FillEllipse(new SolidBrush(Color.Gray), x + 3, y + 3, TileSize - 6 , TileSize - 6);
} else { }
color = Color.Black; if (tile.IsForest ()) {
PaintImage (g, x, y, Forest);
}
if (tile.IsHuntable ()) {
PaintImage (g, x, y, BowAndArrow);
} }
g.FillRectangle(new SolidBrush(color), posx, posy, TileSize, TileSize);
} }
public void PaintEntities (Graphics g) public void PaintEntities (Graphics g)
{ {
IEnumerable<IPositionable> dragons = Backend.GetDragons (); IEnumerable<IEntity> dragons = Backend.GetDragons ();
IEnumerable<IPositionable> players = Backend.GetPlayers (); IEnumerable<IEntity> players = Backend.GetPlayers ();
foreach (IPositionable dragon in dragons) { foreach (IEntity dragon in dragons) {
PaintEntity (g, dragon, Color.Red); int id = dragon.GetId();
if (!dragonImageMappings.ContainsKey(id))
{
dragonImageMappings[id] = random.Next (3);
} }
foreach (IPositionable player in players) { Image image;
PaintEntity (g, player, Color.LightGreen); switch (dragonImageMappings[id])
{
case 0:
image = Dragon1;
break;
case 1:
image = Dragon2;
break;
case 2:
image = Dragon3;
break;
default:
throw new Exception("dragonImageMapping '" + dragonImageMappings[id] + "' doesn't exist");
} }
PaintImage(g, dragon.GetX() * TileSize, dragon.GetY() * TileSize, image);
}
foreach (IEntity player in players) {
PaintImage(g, player.GetX() * TileSize, player.GetY () * TileSize, Knight);
}
}
public void PaintImage (Graphics g, int posx, int posy, Image image)
{
int x = posx + (TileSize - image.Width) / 2;
int y = posy + (TileSize - image.Height) / 2;
g.DrawImage(image, x, y, image.Width, image.Height);
} }
public void PaintEntity (Graphics g, IPositionable entity, Color color) public void PaintEntity (Graphics g, IPositionable entity, Color color)
{ {
int x = entity.GetX () * TileSize + TileSize / 2 - EntitySize / 2;
int y = entity.GetY () * TileSize + TileSize / 2 - EntitySize / 2;
g.FillRectangle (new SolidBrush (color), x, y, EntitySize, EntitySize);
g.DrawRectangle (new Pen( new SolidBrush (Color.Black)), x, y, EntitySize, EntitySize);
} }
} }
} }

View File

@@ -119,7 +119,7 @@ namespace WorldOfPeacecraft
ProcessChallenge (block); ProcessChallenge (block);
break; break;
case MessPlayer: case MessPlayer:
ProcessPlayer (block); ProcessPlayerSelf (block);
break; break;
case MessYourid: case MessYourid:
ProcessYourid (block); ProcessYourid (block);
@@ -287,6 +287,15 @@ namespace WorldOfPeacecraft
Challenge c = new Challenge(id, type, accepted); Challenge c = new Challenge(id, type, accepted);
} }
private void ProcessPlayerSelf (Block playerBlock)
{
Player self = MapPlayer (playerBlock);
lock (Backend) {
Backend.SetSelfId(self.GetId());
Backend.SetPlayer(self);
}
Backend.RefreshGui ();
}
private void ProcessPlayer (Block playerBlock) private void ProcessPlayer (Block playerBlock)
{ {

View File

@@ -8,45 +8,45 @@ namespace WorldOfPeacecraft
[StructLayout(LayoutKind.Sequential)] [StructLayout(LayoutKind.Sequential)]
private struct PathNode private struct PathNode
{ {
[MarshalAs(UnmanagedType.U4)] [MarshalAs(UnmanagedType.I4)]
public uint X; public int X;
[MarshalAs(UnmanagedType.U4)] [MarshalAs(UnmanagedType.I4)]
public uint Y; public int Y;
} }
public static unsafe LinkedList<Coordinate> FindPath (Coordinate posFrom, Coordinate posTo, Map map) public static unsafe LinkedList<Coordinate> FindPath (Coordinate posFrom, Coordinate posTo, Map map)
{ {
PathNode nFrom; PathNode nFrom;
nFrom.X = (uint) posFrom.X; nFrom.X = posFrom.X;
nFrom.Y = (uint) posFrom.Y; nFrom.Y = posFrom.Y;
PathNode nTo; PathNode nTo;
nTo.X = (uint) posTo.X; nTo.X = posTo.X;
nTo.Y = (uint) posTo.Y; nTo.Y = posTo.Y;
Tile[,] tiles = map.GetTiles(); Tile[,] tiles = map.GetTiles();
uint mapWidth = (uint) tiles.GetLength (0); int mapWidth = tiles.GetLength (0);
uint mapHeight = (uint) tiles.GetLength (1); int mapHeight = tiles.GetLength (1);
bool* boolMap = stackalloc bool[(int)(mapWidth * mapHeight)]; bool* boolMap = stackalloc bool[mapWidth * mapHeight];
for (int y = 0; y < mapHeight; y++) { for (int y = 0; y < mapHeight; y++) {
for (int x = 0; x < mapWidth; x++) { for (int x = 0; x < mapWidth; x++) {
boolMap [x + y * mapWidth] = tiles [x, y].IsWalkable (); boolMap [x + y * mapWidth] = tiles [x, y].IsWalkable ();
} }
} }
PathNode* result = stackalloc PathNode[(int) (mapHeight * mapWidth)]; PathNode* result = stackalloc PathNode[mapHeight * mapWidth];
uint noSteps = findPath (nFrom, nTo, mapWidth, mapHeight, boolMap, result); int noSteps = findPath (nFrom, nTo, mapWidth, mapHeight, boolMap, result);
LinkedList<Coordinate> mappedResult = new LinkedList<Coordinate>(); LinkedList<Coordinate> mappedResult = new LinkedList<Coordinate>();
for (int i = 0; i < noSteps; i++) { for (int i = 0; i < noSteps; i++) {
mappedResult.AddLast(new Coordinate((int) result[i].X, (int) result[i].Y)); mappedResult.AddLast(new Coordinate(result[i].X, result[i].Y));
} }
return mappedResult; return mappedResult;
} }
[DllImport("pathfinding")] [DllImport("pathfinding")]
[return: MarshalAs(UnmanagedType.U4)] [return: MarshalAs(UnmanagedType.I4)]
private static extern unsafe uint findPath( private static extern unsafe int findPath(
PathNode posFrom, PathNode posFrom,
PathNode posTo, PathNode posTo,
[MarshalAs(UnmanagedType.U4)] uint mapWidth, [MarshalAs(UnmanagedType.I4)] int mapWidth,
[MarshalAs(UnmanagedType.U4)] uint mapHeight, [MarshalAs(UnmanagedType.I4)] int mapHeight,
bool* map, bool* map,
PathNode* result); PathNode* result);
} }

View File

@@ -13,6 +13,11 @@ namespace WorldOfPeacecraft
Coords = null; Coords = null;
} }
public bool HasMoreSteps()
{
return Coords != null && Coords.Count >= 2;
}
public string NextStep () public string NextStep ()
{ {
if (Coords == null) { if (Coords == null) {
@@ -30,13 +35,13 @@ namespace WorldOfPeacecraft
} }
string command; string command;
if (src.X > dst.X) { if (src.X > dst.X) {
command = "mv:dwn";
} else if (src.X < dst.X) {
command = "mv:up";
} else if (src.Y > dst.Y) {
command = "mv:lft"; command = "mv:lft";
} else if (src.Y < dst.Y) { } else if (src.X < dst.X) {
command = "mv:rgt"; command = "mv:rgt";
} else if (src.Y > dst.Y) {
command = "mv:up";
} else if (src.Y < dst.Y) {
command = "mv:dwn";
} else { } else {
command = NextStep (); command = NextStep ();
} }