I am trying to use Mouse.GetState() for my menu selection. Currently, it will only highlight if I hover over a region left and up from where the menu is. I used DrawString to display the mouses coordinates and found that the 0,0 point wasn't in the top left of my monitor or in the top left of the game window. It was somewhere about 100,100 pixels from the top left of the screen. Also, the 0,0 point moves every time I run the programme.
I looked at others people who have had the same problem but wasn't able to solve it. I tried using Mouse.WindowHandle = this.Window.Handle; in my Initialize() but it didn't nothing. I have two monitors and when I forced the game in fullscreen it would open on my second monitor so I disabled it but the problem remains.
here is a link to my code http://pastebin.com/PNaFADqp
Game1 class:
public class Game1 : Game
{
GraphicsDeviceManager graphics;
SpriteBatch spriteBatch;
SpriteFont spriteFont;
public const int WINDOW_HEIGHT = 800;
public const int WINDOW_WIDTH = 600;
public int tree;
public TitleScreen titleScreen;
public SATDemo satDemo;
public SeparatingAxisTest separatingAxisTest;
public SATWithAABB sATWithAABB;
GameState currentState;
public static Dictionary<string, Texture2D> m_textureLibrary = new Dictionary<string, Texture2D>();
public static Dictionary<string, SpriteFont> m_fontLibrary = new Dictionary<string, SpriteFont>();
public Game1()
{
graphics = new GraphicsDeviceManager(this);
Content.RootDirectory = "Content";
graphics.PreferredBackBufferHeight = WINDOW_HEIGHT;
graphics.PreferredBackBufferWidth = WINDOW_WIDTH;
}
protected override void Initialize()
{
Mouse.WindowHandle = this.Window.Handle;
//enable the mousepointer
IsMouseVisible = true;
currentState = GameState.TitleScreen;
//sets the windows mouse handle to client bounds handle
base.Initialize();
}
public void RequestSATDemo()
{
currentState = GameState.RequestSATDemo;
}
protected override void LoadContent()
{
// Create a new SpriteBatch, which can be used to draw textures.
spriteBatch = new SpriteBatch(GraphicsDevice);
m_textureLibrary.Add("Pixel", Content.Load<Texture2D>("White_Pixel"));
m_fontLibrary.Add("Font", Content.Load<SpriteFont>("MotorwerkOblique"));
titleScreen = new TitleScreen();
satDemo = new SATDemo();
separatingAxisTest = new SeparatingAxisTest();
sATWithAABB = new SATWithAABB();
}
public void RequestSeparatingAxisTest()
{
currentState = GameState.SeparatingAxisTest;
}
public void RequestSATWithAABB()
{
currentState = GameState.SATWithAABB;
}
protected override void Update(GameTime gameTime)
{
MouseTestState = Mouse.GetState();
switch (currentState)
{
case GameState.TitleScreen:
{
titleScreen.Update(gameTime);
break;
}
case GameState.SeparatingAxisTest:
{
separatingAxisTest.Update(gameTime);
break;
}
case GameState.SATWithAABB:
{
sATWithAABB.Update(gameTime);
break;
}
case GameState.Exit:
{
Exit();
break;
}
default:
{
titleScreen.Update(gameTime);
break;
}
}
base.Update(gameTime);
}
protected override void Draw(GameTime gameTime)
{
spriteBatch.Begin();
spriteBatch.DrawString(m_fontLibrary["Font"], MouseTestState.ToString(), new Vector2(0, 0), Color.White);
switch (currentState)
{
case GameState.TitleScreen:
{
titleScreen.Draw(spriteBatch, spriteFont);
break;
}
case GameState.SeparatingAxisTest:
{
separatingAxisTest.Draw(gameTime, spriteBatch);
break;
}
case GameState.SATWithAABB:
{
sATWithAABB.Draw(gameTime, spriteBatch);
break;
}
case GameState.Exit:
{
Exit();
break;
}
default:
{
titleScreen.Update(gameTime);
break;
}
}
spriteBatch.End();
base.Draw(gameTime);
}
}
TitleScreen class:
public class TitleScreen : Screen
{
List<Button> buttonList = new List<Button>();
public Menu mainMenu;
public TitleScreen()
{
mainMenu = new Menu(new Vector2(200, 100), buttonList, 0);
buttonList.Add(new PushButton("Separating Axis Test"));
buttonList.Add(new PushButton("SAT With AABB"));
buttonList.Add(new PushButton("Awesome"));
buttonList.Add(new PushButton("Awesomere"));
buttonList.Add(new PushButton("Awesomere"));
}
public override void Update(GameTime gametime)
{
mainMenu.Update(gametime);
}
public void Draw(SpriteBatch sB, SpriteFont sF)
{
mainMenu.Draw(sB, sF);
}
}
PushButton class:
public class PushButton : Button
{
string m_text;
SpriteFont m_font;
Color m_static, m_onClick, m_onHover;
Texture2D m_sprite2D, m_onClick2D;
static public int Pbuttoncount;
//click processing
bool m_clickedInside = false,
m_releasedInside = false,
m_OnClicked = false,
selected = false;
Rectangle drawRectangle;
public PushButton(string Text)
{
m_text = Text;
drawRectangle = new Rectangle((int)Menu.m_position.X, (int)Menu.m_position.Y + (15 * Pbuttoncount), 200, 15);
ButtonRegion = new Rectangle((int)Position.X, (int)Position.Y, 200, 15);
Pbuttoncount++;
}
public PushButton(Rectangle ButtonRegion, SpriteFont Font, string Text, Color Static, Color OnClick, Color OnHover)
{
m_buttonRegion = ButtonRegion;
m_font = Font;
m_text = Text;
m_static = Static;
m_onClick = OnClick;
m_onHover = OnHover;
// drawRectangle = ButtonPosition(m_buttonRegion);
}
public PushButton(Rectangle ButtonRegion, Texture2D Sprite2D, Texture2D OnClick2D)
{
m_buttonRegion = ButtonRegion;
m_sprite2D = Sprite2D;
m_onClick2D = OnClick2D;
//drawRectangle = ButtonPosition(m_buttonRegion);
}
public override void Update(GameTime gameTime)
{
MouseState currentMouse = Mouse.GetState();
selected = MouseState(drawRectangle, currentMouse);
m_clickedInside = ClickInside(currentMouse, m_lastMouseState);
ReleaseInside(currentMouse, m_lastMouseState);
if (selected && m_clickedInside && m_releasedInside)
m_OnClicked = true;
else
m_OnClicked = false;
m_lastMouseState = currentMouse;
}
public override void Draw(SpriteBatch spriteBatch, SpriteFont spriteFont, int buttonCount, Vector2 Position)
{
spriteBatch.Draw(Game1.m_textureLibrary["Pixel"], new Rectangle((int)Position.X + 10, (int)(Position.Y + 15 * buttonCount), 180, 15), Color.Wheat);
if (selected)
spriteBatch.DrawString(Game1.m_fontLibrary["Font"], m_text, new Vector2(Position.X + 15, Position.Y + 15 * buttonCount), Color.Orange);
else
spriteBatch.DrawString(Game1.m_fontLibrary["Font"], m_text, new Vector2(Position.X + 15, Position.Y + 15 * buttonCount), Color.Black);
}
}
Menu class:
public class Menu
{
List<Button> m_buttonList;
float m_transparency;
public int n = 0;
public Rectangle buttonRegion, m_menuRegion, m_dimensions;
static public Vector2 m_position;
int m_WINDOW_HEIGHT = Game1.WINDOW_HEIGHT;
int m_WINDOW_WIDTH = Game1.WINDOW_WIDTH;
private Game1 m_managerClass;
public Menu(Vector2 Position, List<Button> ButtonList, float Transparency)
{
m_position = Position;
m_buttonList = ButtonList;
m_transparency = Transparency;
m_managerClass = new Game1();
}
public Rectangle MenuRegion
{
get { return m_menuRegion; }
set { m_menuRegion = value; }
}
static public Vector2 Position
{
get { return m_position; }
}
public void Update(GameTime gametime)
{
for (int i = 0; i < m_buttonList.Count; i++)
{
m_buttonList[i].Update(gametime);
if (m_buttonList[0].OnClicked)
{
SeperatingAxisTest();
}
}
}
public void Draw(SpriteBatch sB, SpriteFont sF)
{
sB.Draw(Game1.m_textureLibrary["Pixel"], new Rectangle((int)m_position.X - 5, (int)m_position.Y - 10, (m_buttonList[0].ButtonRegion.Width + 10), (m_buttonList[0].ButtonRegion.Height * m_buttonList.Count) + 20), Color.Blue);
for (int i = 0; i < m_buttonList.Count; i++)
{
m_buttonList[i].Draw(sB, sF, i, new Vector2(Position.X, Position.Y));
}
}
private void SeperatingAxisTest()
{
m_managerClass.RequestSeparatingAxisTest();
}
}
Program class:
public static class Program
{
[STAThread]
static void Main()
{
using (var game = new Game1())
game.Run();
}
}
Let me know if you need anything else. I'm still learning and will sell my soul to you for an answer.
Your Menu class is creating a new instance of Game1. This is, most likely, not what you want, since Game1 is instantiated in the entry point for you app. The Game1 instance has an instance of TitleScreen, which in turn has an instance of the Menu class, so a Menu should have no business creating its own game.
When this (other) instance is created, it invokes platform-specific (Windows) methods, creates an additional window handle (which is never shown) and configures the Mouse.WindowHandle.
And btw, setting WindowHandle manually does absolutely nothing in Monogame, so all these sources mentioning that are talking about XNA.
So, there are several remarks:
You should probably have a "screen manager" class which contains the current screen. It is strange to have a field of type TitleScreen in your game class, it should at least be of the base type (Screen), so that the game class draws and updates each screen transparently.
If you need a reference to the game class anywhere, don't instantiate a new one, but rather pass it along through the constructor.
m_managerClass is a bad name for a field which is actually a Game. Also google for C# naming conventions. Perhaps you even might want to download an existing monogame game template, e.g. check some of the samples online; the NetRumble sample seems to implement a screen manager.
Remove the Mouse.WindowHandle line, it should be set to your one-and-only game window by default.
tl;dr add the Game1 as a parameter wherever you might need it (but only where you need it).
abstract class Screen
{
private readonly Game1 _game;
public Game1 Game
{ get { return _game; } }
public Screen(Game1 game)
{
_game = game;
}
}
class TitleScreen : Screen
{
public TitleScreen(Game1 game)
: base(game)
{ ... }
}
class Menu
{
private readonly Screen _screen;
public Menu(Screen parentScreen, Vector2 pos, List<Button> list, float alpha)
{
_screen = parentScreen;
...
// if you need the game instance, just use _screen.Game
}
}
I am testing UNET (Unity 5.2) but is running into problem with things that probably should be very simple.
I have an Orange fruit (GameObject) that i can drag and have attached the network transform in code. When releasing the mouse (Mouse Up) I want to release the ownership of the Orange so none owns it, want later to attach to another player. I have tested with ReplacePlayerForConnection and a few other things but totally screwed up the code.
I have now reset everything and must ask for some help how to do this.
The scripts i have, attached to the Orange GameObject, is:
1
using UnityEngine;
using UnityEngine.Networking;
using System.Collections;
public class orange : NetworkBehaviour {
float distance = 10;
void Start() {
if (isLocalPlayer) {
//GameObject.Find("Main Camera").SetActive(false);
}
}
void OnMouseDrag() {
Vector3 mousePosition = new Vector3 (Input.mousePosition.x, Input.mousePosition.y, distance);
Vector3 objPosition = Camera.main.ScreenToWorldPoint (mousePosition);
transform.position = objPosition;
}
void OnMouseUp() {
print (">>> MOUSE UP <<<");
if (isLocalPlayer) {
GetComponent<NetworkIdentity> ().localPlayerAuthority = false;
GetComponent<NetworkIdentity> ().serverOnly = false;
}
}
Here is scrip #2 attached to the Orange GameObject:
using UnityEngine;
using UnityEngine.Networking;
using System.Collections;
public class Orange_SyncPosition : NetworkBehaviour {
[SyncVar] // Server will automatically transmit this value to all players when it changes
private Vector3 syncPos;
[SerializeField] Transform myTransform;
[SerializeField] float lerpRate = 15;
void FixedUpdate () {
TransmitPosition ();
LerpPosition ();
}
void LerpPosition() {
if (!isLocalPlayer) {
myTransform.position = Vector3.Lerp(myTransform.position, syncPos, Time.deltaTime *lerpRate);
}
}
[Command]
void CmdProvidePositionToServer (Vector3 pos) {
syncPos = pos;
}
[ClientCallback]
void TransmitPosition () {
if (isLocalPlayer) {
CmdProvidePositionToServer (myTransform.position);
}
}
}
Use NetworkServer.ReplacePlayerForConnection():
// Player is a NetworkBehaviour on the existing player object
void ReplacePlayer (Player existingPlayer) {
var conn = existingPlayer.connectionToClient;
var newPlayer = Instantiate<GameObject>(playerPrefab);
Destroy(existingPlayer.gameObject);
NetworkServer.ReplacePlayerForConnection(conn, newPlayer, 0);
}
Use AssignClientAuthority / RemoveClientAuthority
And never touch these parameters at runtime:
GetComponent<NetworkIdentity> ().localPlayerAuthority = false;
GetComponent<NetworkIdentity> ().serverOnly = false;
I am trying to port the Java code below to Dart and am puzzled about to do this.
In Java the Iterable interface is where clean with one method and to implement this is a snap.
How is this code best transformed to Dart?
/**
* Chess squares represented as a bitmap.
*/
public class ChessSquares implements Iterable<ChessSquare> {
private static class ChessSquaresIterator implements Iterator<ChessSquare> {
long bits;
int nextBit;
public ChessSquaresIterator(long bits) {
this.bits = bits;
nextBit = Long.numberOfTrailingZeros(bits);
}
#Override
public boolean hasNext() {
return (nextBit < 64);
}
#Override
public ChessSquare next() {
ChessSquare sq = ChessSquare.values()[nextBit];
bits = bits & ~sq.bit;
nextBit = Long.numberOfTrailingZeros(bits);
return sq;
}
#Override
public void remove() {
throw new UnsupportedOperationException();
}
}
#Override
public Iterator<ChessSquare> iterator() {
return new ChessSquaresIterator(bits);
}
...
By using IterableMixin you only need to implement the iterator-function.
class ChessSquares with IterableMixin<ChessSquare> {
#override
Iterator<ChessSquare> get iterator => new ChessSquaresIterator(bits);
...
}
Visit http://blog.sethladd.com/2013/03/first-look-at-dart-mixins.html for a short introduction on mixins.
The Iterator-interface is straight forward. You only have to implement the function moveNext and the getter current.
Soo I tried this which is kind of not what I want since I do not want to extend a base class.
/**
* Chess squares represented as a bitmap.
*/
class ChessSquares extends IterableBase<ChessSquare> {
Iterator<ChessSquare> get iterator {
return new ChessSquaresIterator(this);
}
...
}
class ChessSquaresIterator extends Iterator<ChessSquare> {
int _nextBit;
int64 _bits;
ChessSquare _current;
ChessSquaresIterator(ChessSquares squares) {
_bits = new int64.fromInt(squares._bits);
}
bool moveNext() {
_nextBit = _bits.numberOfTrailingZeros();
if (_nextBit < 64) {
_current = ChessSquare.values()[_nextBit];
_bits = _bits & ~_current.bit();
} else {
_current = null;
}
return _nextBit < 64;
}
E get current => _current;
}
I am using mapField to create a custom map.I am using the code in this link.
How to show more than one location in Blackberry MapField?.
But the map position is fixed. i am not able to drag the map as we can do in google maps or when we invoke the maps like
public void execute(ReadOnlyCommandMetadata metadata, Object context)
{
Invoke.invokeApplication(Invoke.APP_TYPE_MAPS, new MapsArguments());
}
Here's some code that should get you going on the correct path. I've taken it from a project of mine that had some special requirements, so there could be some remnants of that left in there inadvertently. There will be some undefined variables in there -- they're member variables that are declared in the class and should all start with an underscore. This is also part of a class that extends MapField, so you would have to create a custom map class and then use that rather than the default.
protected boolean touchEvent(TouchEvent message) {
boolean ret = super.touchEvent(message);
//mark that we're starting to interact
if(message.getEvent() == TouchEvent.DOWN) {
_startTouchTracking = true;
_clicking = true;
_touchX = message.getX(1);
_touchY = message.getY(1);
}
//user is wanting to move the map
else if(message.getEvent() == TouchEvent.MOVE) {
int dx = _touchX - message.getX(1);
int dy = _touchY - message.getY(1);
_clicking = false;
_touchX = message.getX(1);
_touchY = message.getY(1);
//perform checks to make sure we don't move outside of the map's range
int lat = getLatitude() - dy*(int)MathUtilities.pow(2, (double)getZoom());
if(lat < -9000000) {
lat = -9000000;
}
else if (lat > 9000000) {
lat = 9000000;
}
int lon = getLongitude() + dx*(int)MathUtilities.pow(2, (double)getZoom());
if(lon < -18000000) {
lon = -18000000;
}
else if (lon > 18000000) {
lon = 18000000;
}
moveTo(lat, lon);
}
//if the person just touches and releases, we want to move to that spot
else if (message.getEvent() == TouchEvent.UNCLICK && _clicking) {
int dx = message.getX(1) - getWidth()/2;
int dy = message.getY(1) - getHeight()/2;
move(dx, dy);
_clicking = false;
}
//touch has been released
else if (message.getEvent() == TouchEvent.UP) {
_startTouchTracking = false;
}
//we handled the click
return true;
}
As said, this might need tweaking for your use, but in general should get you started. The MathUtilities.pow() calls were my way of coming up with an appropriate amount of motion depending on the zoom level.
Edit for Comments
Letting a Bitmap move with the map:
protected Coordinates _bitmapCoordinates;
protected Bitmap _bitmap;
public YourMapField() {
//we're going to put the bitmap at -38.43, 20.32
_bitmapCoordinates = new Coordinates(-38.43, 20.32, 0.0);
_bitmap = YOUR_CODE_TO_GET_THE_BITMAP;
}
protected void paint(Graphics g) {
super.paint(g);
XYPoint placeToPaintBitmap = new XYPoint();
convertWorldToField(_bitmapCoordinates, placeToPaintBitmap);
//perform a check here to make sure that field will be seen. This code would depend
//on how you're painting the image. Just check the placeToPaintBitmap.x and placeToPaintBitmap.y
//against 0 and the map's width and height, along with some adjustment for how you paint
if(bitmap will be visible on the screen) {
//The code I have here is drawing the bitmap from the top left of the image, but if
//you need to draw from some other place you may have to offset the x and y
g.drawBitmap(placeToPaintBitmap.x, placeToPaintBitmap.y, _bitmap.getWidth(), _bitmap.getHeight(), 0, 0);
}
}
I didn't test any of that code, so it might be buggy but should give you the general idea.
package {
import flash.display.Sprite;
import flash.events.Event;
import flash.events.KeyboardEvent;
import flash.ui.Keyboard;
public class helloworld extends Sprite {
public static var x:int = 0;
public static var y:int = 0;
public function helloworld() {
graphics.lineStyle(1, 0, 1);
stage.focus = this;
stage.addEventListener(KeyboardEvent.KEY_DOWN, onKeyDown);
}
private function onKeyDown(event:KeyboardEvent):void {
if (event.keyCode == Keyboard.DOWN)
{
y++;
graphics.moveTo(x,y);
graphics.drawCircle(x, y, 10);
}
if (event.keyCode == Keyboard.RIGHT)
{
x++;
graphics.moveTo(x,y);
graphics.drawCircle(x, y, 10);
}
}
}
The circles that are drawn first also move. How can I stop it from doing that?
You think you're using your public static x & y values, but actually you're using the Sprite's built in x and y properties which control its location on the stage. When you use y++ and x++ it moves the entire sprite down/right.
You should either make sure you're always calling helloworld.x && helloworld.y (bad idea, easy to forget).
OR
You should not use variables named x and y. Try: circleX and circleY or something that is more descriptive of what you're using it for.